Reputation: 3810
I'm building a simple AngularJS app, but I couldn't solve a problem regarding services, ng-repeat and dynamically added data.
What I'm trying to do
My page is splitted into few countrollers.
In the homeController
I have a text field and a button. When I press the button I'm doing an API call to the server, the server returns JSON and I'm setting the data to Storage
service. In this part everything is OK - The server returns data as it should and the data is setted to the service and I'm getting console.log('Data set!');
in the Storage service. In the second controller ( slidesController
) I'm having a ng-repeat
<div ng-controller="slidesCtrl">
<div ng-repeat="current in paragraphs"> test </div>
</div>
And as you can see in my code below, paragraphs
is binded to Storage.data
value in slidesCtrl
So, when a user enter something in the box and press the button (homeCtrl), the server should pass the returned data to Storage
service and render the data using ng-repeat (slideCtrl). If I hardcode the data in Storage server with [2, 3, 4, 5] for example, everything is ok ( I'm getting test 4 times, because of ng-repeat ), but if the data is taken with api call, ng-repeat isn't working.
Code
App.controller('homeCtrl', function ($scope, $http, Api) {...
$scope.onprocess = function () {
$scope.loading = true;
Api(.....);
}
});
App.controller('slidesCtrl', function ($scope, Storage) {
$scope.paragraphs = Storage.data.paragraphs; // NOT WORKING IF DATA IS DYNAMICALLY ADDED
$scope.paragraphs = Storage.test; // IF DATA IS PREDEFINED EVERYTHING IS FINE
});
App.factory('Api', function ($http, Storage) {
return function (data) {
$http.post('/api', {
url: data.url,
analyze: 0
}).success(function (res) {....
Storage.set(res);....
}).error(function () {....
});
};
});
App.factory('Storage', function () {
var output = {};
var set = function (data) {
output = data;
console.log('Data set!');
};
return {
set: set,
data: output,
test: [1, 2, 3]
};
});
Upvotes: 1
Views: 2377
Reputation: 3810
I found
angular.copy(data, output);
as solution.
You can see more information on this topic Sharing dynamic data between two controllers with service AngularJS
Thanks to everyone.
Upvotes: 1
Reputation: 12467
The problem is with how you've defined your Storage
service.
In the set
function, you're assigning directly to the output
local variable, which will not automatically update the data
property of the object the factory returns.
To illustrate the problem:
var output = {foo: 1, bar: 2};
function set(somenewdata) {
output = somenewdata;
}
var obj = {data: output};
// obj == {data: {foo: 1, bar: 2}}
set({baz: 3});
// output == {baz: 3}
// but, obj == {data: {foo: 1, bar: 2}}
So if you change your Storage service to something like:
App.service('Storage', function() {
this.data = {};
this.set = function(newdata) {
this.data = newdata;
};
});
When a controller binds a property to Storage.data
, the data will actually be updated.
Upvotes: 0
Reputation: 6089
I suspect that this is due to the lag in a AJAX
call and angular executes the service before a AJAX
call. As none of the scopes are changing, angular is not detecting a change and hence its not reflecting on your
Use a getter in Storage service to get the paragraphs and call that getter method from slidesCtrl
, like this.
App.controller('slidesCtrl', function($scope, Storage) {
$scope.paragraphs = Storage.getParagraphs();
});
And in your service, you can use it like this.
App.factory('Storage', function() {
var output = {};
var set = function(data) {
output = data;
console.log('Data set!');
};
return {
set: set,
getParagraphs: function () {
return output && output.paragraphs;
}
};
});
Upvotes: 0