Search code examples
javascriptangularjsangularjs-directivehrefangularjs-controller

AngularJS - href redirect to same domain cause page display before data are ready


I'm using Angular 1.4.1. I made a directive, a generic card with thumbnail and a link. The link is a generic absolute url, but usually lead to somewhere inside the app.

So assuming I am in https://stackoverflow.com/section/ there could be a card with a link like https://stackoverflow.com/section/detail

I have an app.js similar to this (I just post the interested route section)

.state('base.section', {
          url: 'section/',
          views: {
              '@': {
                  templateUrl: 'views/section.html',
                  controller: 'SectionController'
              }
          },
          resolve: {
              'items': function (SomeService) {
                  console.log("items resolve triggered");
                  return SomeService.doThingsReturnPromise();
              }
          }
}
.state('base.section.detail', {
          url: 'detail',
          views: {
              '@': {
                  templateUrl: 'views/detail.html',
                  controller: 'DetailController'
              }
          },
          resolve: {
              'items': function (items) {
                  return items;
              },
              'stuff': function(SomeOtherService) {
                  console.log("stuff resolve triggered.");
                  return SomeOtherService.doThingsReturnPromise();
              }
          }
}
                  

So the problem is that when I click

<a ng-href="https://stackoverflow.com/section/detail">

I get correct redirected to the detail page, but before the promise in the resolve is fully resolved and I gets all angular like variables displayed ( {{ somethingLikeThis }} ).

Even if resolve gets triggered, (I can see the log in the console) seems just that Angular doesn't wait till the resolve is complete before loading the controller, as it should behave.

Of course, if I reload the detail page, I get all the values fully loaded. The same if I move to another site section (https://stackoverflow.com/baloons).

The problem seems occur just when I move from "section" to "detail", from the same running app

Hope to have provided a good problem explanation

UPDATE

I solved the problem, but to better understand I want to specify the services functions. They're something like this

angular.module('myApp')
.factory('SomeService', 
function ($resource, serverURL, protocol, requestFormat) {
        return $resource(serverURL + 'backendUrl/',
            {
                callback: 'JSON_CALLBACK',
                format: requestFormat
            },
            {
                doThingsReturnPromise: {
                    method: protocol,
                    isArray: true
                }
            });

});

just for completeness, the problem turned out even using $q.all(promises) in the resolve


Solution

  • The problem solved using .$promise in the resolve (no pun intended)

    resolve: {
        'items': function (SomeService) {
            console.log("items resolve triggered");
            return SomeService.doThingsReturnPromise().$promise;
        }

    I had the same problem with $q.all and the solution was the same, just slightly different

    resolve: {
        'items': function (SomeService, SomeOtherService, $q) {
            var promises = [
                SomeService.doThingsReturnPromise().$promise,
                SomeOtherService.doThingsReturnPromise().$promise
            ];
            return $q.all(promises);
        }
    }

    $q.all return a promise so it works without specifying .$promise, but the services requests have to