1

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]
    };
});
2
  • Please provide a fiddle or a plunk... Commented Dec 23, 2013 at 4:16
  • 1
    This is already solved. I can't mark the answer till tomorrow. @Abilash Commented Dec 24, 2013 at 4:19

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Possible Solution

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;
        }
    };
});

1 Comment

This solution could fix it :(
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.