Reputation: 593
I'm new to angular and I'm facing some problems...
I have two directives that share the same controller and that controller was one service requesting a json file on a async call ($http).
The directives need the same data and both are init almost at the same time, but I want only to make one call and retrieve the data to the controllers and update the view with the data.
MainMenuHeader.js
(function () {
var app = angular.module("mainMenuHeaderModule", ["mainMenuControllerModule"]);
app.directive("mainheader", function () {
return {
restrict: "A",
transclude: true,
templateUrl: "TMainMenuHeader.html",
controller: "mainMenuController",
}
});})();
MainMenuAside.js
(function () {
var app = angular.module("mainMenuAsideModule", ["mainMenuControllerModule"]);
app.directive("mainaside", function () {
return {
restrict: "A",
transclude: true,
templateUrl: "TMainMenuAside.html",
controller: "mainMenuController"
}
});})();
MainMenuController.js
(function () {
var app = angular.module("mainMenuControllerModule", ["mainMenuServiceModule"]);
app.controller("mainMenuController", ["$scope", "MainMenuService",
function ($scope, MainMenuService)
{
$scope.menuList = MainMenuService.GetAsyncData();
console.log("mainMenuController menuList: " + $scope.menuList);
}]);
})
();
MainMenuService.js
(function () {
var module = angular.module("mainMenuServiceModule", []);
module.factory("MainMenuService", ["$q", "$http", function ($q, $http)
{
var data;
var getAsyncData = function()
{
console.log(" -> getting data...");
$http.get("menu.json")
.success(function(result)
{
data = result;
console.log("async data: " + data);
});
return data;
}
var getDataObject = function ()
{
return [
{
id:1,
title: "Menu 1",
submenus: [
{
title: "Sub Menu 1",
itens: [
{ title: "Option 1" },
{ title: "Option 2" },
{ title: "Option 3" }
]
}
]
},
{
id:2,
title: "Menu 2",
submenus: [
{
title: "Sub Menu 2",
itens: [
{ title: "Option 1" },
{ title: "Option 2" },
{ title: "Option 3" },
{ title: "Option 4" },
{ title: "Option 5" }
]
}
]
},
{
id:3,
title: "Menu 3",
submenus: [
{
title: "Sub Menu 3",
itens: [
{ title: "Option 1" },
{ title: "Option 2" },
{ title: "Option 3" }
]
}
]
}
];
}
return {
GetDataObject : function()
{
return getDataObject();
},
GetAsyncData : function()
{
return getAsyncData();
}
}
}]);
})();
The service was two methods. One that return an JS object just for testing, and another with a $http request that is not working.
I also tried return a deferred from the service and wait on the controller for the response, but with out success, maybe I made something wrong... can someone help me out?
I also made a plunker so you see the problem in action...
http://plnkr.co/edit/7NIPeAsUYlh96p3hUij7
Thank you for your time... =)
Upvotes: 0
Views: 733
Reputation: 593
I changed a bit my service... if a another request is made while another is running the reference of data is returned, and everyone who is calling will be update when finished:
module.factory("MainMenuService", ["$http", function ($http)
{
var isRequesting = false;
var data = {};
var getAsyncData = function()
{
if (isRequesting) return data;
isRequesting = true;
console.log(" -> getting async data...");
$http.get("json/mainMenu.json")
.success(function (result)
{
isRequesting = false;
angular.forEach(result, function (value, key)
{
value.id = key;
switch(value.submenus.length)
{
case 1: value.columnsSize = 12; break;
case 2: value.columnsSize = 6; break;
default: value.columnsSize = 4; break;
}
})
data.menuList = result;
console.log(" -> data.menuList : " + data.menuList);
});
return data;
}
return {
GetAsyncData: function ()
{
return getAsyncData();
}
}
}]);
Upvotes: 0
Reputation: 654
good thing you created a plunker.
The problem was in this function of the service:
var data;
var getAsyncData = function()
{
console.log(" -> getting data...");
$http.get("menu.json")
.success(function(result)
{
data = result;
console.log("async data: " + data);
});
return data;
}
basically you're returning an undefined variable to the controller, then make the http request and when you get the response you update data to reference the result, but the in the controller $scope.menuList still points to undefined (you're not updating the returned object from the function).
to fix it you have 2 options:
to bind the view to a property of the object that you return in the service and then update the object property when you get the response from the http call. here's the relevant plunker
other option is that for the async call the in the service you return a promise and once the promise is resolved the controller can update the scope with the result of the request. here's the relevant plunker
Upvotes: 1