0

I've inherited a project from a colleague and I need to troubleshoot some issues. The project uses the Angular UI-Bootstrap module and its directives/services. My colleague has written a custom directive that uses $http to get some data then depending on the returned results populates a template and injects this into the view. This seems fine but I have noticed that when this directive is running (sometimes 20 instances on a view) it blocks other functionality for example Modal Windows provided by UI Bootstrap. When the page loads and the custom directive is loading/waiting for the $http results the click functionality of launching a modal window (or any thing else) seems to have to wait till the majority of the custom directives have executed. The custom directive looks like so (see below), and I have set a priority to 1 but this does nothing... do I need to clone/remove attributes, can anyone see a way I can improve the code I have been given? Should the compile be used rather than the link function? Have can I prevent the blocking nature of this directive?

I also think he has imported / injected some items that are not required (like $q).

in the HTML view

<div data-get-partner-availability data-partner-id="1234"></div>

and the JavaScript / directive:

.directive('getPartnerAvailability', function ($http, $q) {
        return {
            restrict: 'AE',
            priority: 1,
            scope: {
                partnerId: '@partnerId'
            },
            template: '<div class="partner-availability"><img src="../../../img/ajax-loader.gif" /></div>',
            controller: function () {
                return {
                    getAvailability: function (partnerId) {
                        return $http({
                            method: 'GET',
                            url: '/api/partner/:partnerId/getAvailability',
                            params: {
                                'partnerId': partnerId
                            }
                        });
                    }
                };
            },
            link: function (scope, element, attrs, controller) {

                controller.getAvailability(scope.partnerId).then(function (result) {

                    var html = '',
                        container = [];

                    if (typeof result.data !== 'undefined' && typeof result.data.times !== 'undefined' && result.data.times.length > 0) {
                        var isFirst = true;
                        for (var i in result.data.times) {
                            var itemHtml = '';

                            // some nested conditions that create a string called itemHTML

                            html += itemHtml;
                        }
                    } else {
                        html += 'Some message';
                    }

                    element.html(html);
                });
            }
        }
    }

Thanks in advance.

6
  • Are you certain that this directive cause the problem? $http requests are asynchronous. Are other elements dependant on this directive? Maybe open developer tools and check the network tab to confirm that page is actually waiting for http requests before rendering Commented Jun 11, 2014 at 12:03
  • I have used Firebug and Chrome Dev tools and the network tab shows around 20 requests... once the majority of these are complete the click functionality for the modal windows, etc, etc... become active again (e.g. If I click the open modal button, the model isn't opened until the majority of $http requests are complete) Commented Jun 11, 2014 at 12:06
  • THe modal windows themselves create a GET request themselves... this request seems to be placed at the bottom of the all the requests from the directive above. Commented Jun 11, 2014 at 12:09
  • Does the itemHTMl contain some of the modal functionality? Commented Jun 11, 2014 at 12:11
  • No, these requests are completely separate and have no dependencies on each other... Commented Jun 11, 2014 at 12:12

1 Answer 1

2

Most browsers have a limit of the amount of concurrent requests that are allowed per page. You are creating a lot of requests, so the later requests will wait in queue until earlier requests are finished. This will cause the modal to not appear until the earlier requests are finished because the modal $http request will be at the bottom of the queue.

To clean this up, I would first move all data retrieval logic to a service and have the directives call that service. Then in that service you could either maintain a queue of requests and make sure that they aren't all sent at the same time, OR you might want to add a batch functionality to the server api so you can get more than 1 partner availability in 1 go.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. This helped me know the cause of issue I am facing. My priority requests were queued because of the earlier time consuming requests
Can we set priority to any 1 of our request?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.