3

In my factory I have a get request that gets data that is vital to the rest of my app. I am currently using a app.run() function to run my factory when the app is initialized but the http request is taking longer than the rest of the code. If I navigate '/home' and initialize the app and then navigate to '/map' it works perfectly, however if I just navigate to '/map' and initialize it will not work because the data from the get request is not loaded before the page. Does anyone know how I can ensure that my http request is fully run before moving on to the controller and the rest of the program?

Doing some research it seems as though the angular way is to use promises. However, I do not know how one would use a promise to run a factory/ delay a controller or if its even possible. So if you have any thoughts on this or links to documentation it would be appreciated.

my module declaration

angular.module('Ski', [
  'ngRoute'
]).run(function(MountainFactory, $q){
  MountainFactory.fetch();
});

factory where the http request is

angular.module('Ski').factory('MountainFactory', function($http, $q) {
  var mountain = {};
  var fetch = function() {
     $http.get('https://quiet-journey-8066.herokuapp.com/mountains/3')
        .success(function(response) {
            angular.copy(response, mountain);
          });
  };
  return {
    fetch: fetch,
    mountain: mountain
  };
});

controller where I set the scope.

angular.module('Ski').controller('MapCtrl', function($scope, $http, MountainFactory) {
  'use strict';
  $scope.mountain = MountainFactory.mountain;
});

my directive where i set up my map with data from the get request. I did not include this code as its long and distracting, but if the data http request is run and the scope is set this directive works fine, which is why I did not include it.

angular.module('Ski').directive('mapCanvas', function() {

  function link (scope, element, attrs) {
      //code here where I make a map.

    }
    return {

      scope: {
        lat: '@',
        lng: '@',
        map: '@map'
      },

      link: link,

    };
  });

map.html --> the route of '/map'

<div ng-controller="MapCtrl">
  <h1>{{mountain.name}}</h1>
   <div map-canvas lat="{{lat}}" lng="{{lng}}" id="map-canvas" style="width: 500px; height: 500px;"></div>
  <div ng-controller="MarkerCtrl">
    <a ng-click="makeMarker()"> New Marker </a>
    <button ng-click="makeMarker()"type="button" class="btn btn-primary">Create</button>
  </div>
</div>
Billy
  • 823
  • 3
  • 12
  • 28
  • 1
    you can use a Watcher to update the whole view when the value changed, but you should manage everything simply in the promise completion (success) – sam Dec 16 '14 at 16:29
  • 1
    if you need a certain set of data to always be available *before* your angular app runs, have a look at this answer [Initialize AngularJS service with asynchronous data](http://stackoverflow.com/a/19871327/2943490) – user2943490 Dec 16 '14 at 23:16

1 Answers1

1

Here I have an app.js where I register my modules... So I can set my controllers like this:

.state('app.registro', {
      url: "/registro",
      views: {
        'menuContent' :{
          templateUrl: "templates/registro.html",
          controller: 'RegistroCtrl'
            //resolve: {
            //    cordova: function($q) {
            //    var deferred = $q.defer();
            //    ionic.Platform.ready(function() {
            //        console.log('ionic.Platform.ready');
            //        deferred.resolve();
            //    });
            //    return deferred.promise;
            //    }
            //}
        }
      }
    })

The commented block is where you would make your request. Making this, controller waits for the request...

quicoli
  • 612
  • 5
  • 12
  • Hi. Yes. Take a look into this: [https://docs.angularjs.org/api/ngRoute/service/$route] and see the script.js file. You'll see the 'resolve' clause, which is the place you should make your call. – quicoli Dec 17 '14 at 17:23