Data Not Defined In Link Function After $http Request In Angular
Solution 1:
If you're using angular ui-router
you could also use resolve
. With resolve
you can do the $http
before the controller starts.
You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.
from the docs.
Please have a look at the demo below or this jsfiddle.
angular.module('demoApp', ['ui.router'])
.config(function ($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('home', {
url: '/',
template: '<ratehome></ratehome><ratehome></ratehome><ratehome></ratehome>',
controller: 'mainCtrl',
resolve: {
artists: function (artistsService) {
console.log('Resolve');
return artistsService.get(); //'/artistsearch',//artistsService.get();
}
}
});
})
.controller('mainCtrl', ['$scope', '$http', '$location', 'artists', MainCtrl])
.directive('ratehome', function () {
return {
restrict: "E",
template: '<div id="rateYo"><ul><li ng-repeat="artist in recentArtist">{{artist}}</li></ul></div>',
link: function (scope, elem, attrs) {
console.log("NEW", scope.recentArtist);
}
}
})
.factory('artistsService', function ($http) {
return {
get: function () {
console.log('getting');
return $http({
method: 'GET',
url: 'http://crossorigin.me/http://www.mocky.io/v2/558b30615f3dcbc414067170', //'/artistsearch',//params: {getArtist: "all"}
}).then(function (recent) {
//console.log(recent);return recent.data;
});
}
};
});
functionMainCtrl($scope, $http, $location, artists) {
$scope.recentArtist = artists;
console.log('ctrl', artists);
}
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script><divng-app="demoApp"><divui-view=""></div></div>
Solution 2:
AS your directive is not using isolated scope
, that does mean you can directly access your controller scope inside your directive. I'd suggest you to to put that $watch
inside directive link
instead of your controller. That would intimate you that the ajax has been completed and data got changed & you get those changed value inside watcher
function.
Code
.directive('ratehome',function(){
return {
restrict:"E",
template: "<div id='rateYo'></div>",
link: function(scope, ele, attrs){
$scope.$watch('recentArtist',function(newValue,oldValue){
console.log("NEW",newValue)
});
}
}
})
Solution 3:
Your link function is running before the $http response comes back as you suspect. You can wait for it by using $broadcast and $on:
angular.module('LiveAPP.main',['LiveAPP.factory'])
.controller('mainCtrl', ['$scope','$http', '$location','$rootScope','dataFactory',mainCtrl])
.directive('ratehome',function(){
return {
restrict:"E",
template: "<div id='rateYo'></div>",
link: function(scope, ele, attrs){
scope.$on('artistLoaded', function(){
console.log("NEW",scope.recentArtist);
});
}
};
});
functionmainCtrl($scope,$http,$location,$rootScope,dataFactory){
$scope.getRecentArtists = function(){
return$http({
method: 'GET',
url: '/artistsearch',
params: {getArtist: "all"}
}).then(function(recent){
$scope.recentArtist = recent.data
$rootScope.$broadcast('artistLoaded');
});
};
$scope.getRecentArtists();
$scope.recentArtist = "";
$scope.$watch('recentArtist',function(newValue,oldValue){
$scope.recentArtist = newValue
});
}
This way the code will not run until the response has been returned and set
Post a Comment for "Data Not Defined In Link Function After $http Request In Angular"