Jason
Jason

Reputation: 119

AngularJS timing issue when exposing data in a service to components on the same page

I am trying to use multiple components on a composite page and reference data from a common service. The problem is that I am trying to instantiate the object in the service from within the first component and then reference it in the second component; if I put the second component ahead of my first component, my value object hasn't been instantiated yet and the second component fails to show anything.

I was hoping two-way data binding would save me, but it isn't.

Composite HTML

<second-component></second-component>
<first-component></first-component>

First Component

angular.
module('simple').
component('firstComponent', {
    template: "<h3>Component 1</h3><ul ng-repeat='val in $ctrl.someVals'><li>{{val}}</li></ul>",
    controller: function(factory) {
        'use strict';
        // Responsible for creating an object in the service
        factory.changeData();
        this.someVals = factory.vals;
    }
});

Second Component

angular.
module('simple').
component('secondComponent', {
    template: "<h3>Component 2</h3><ul ng-repeat='val in $ctrl.someVals'><li>{{val}}</li></ul>",
    controller: function(factory) {
        'use strict';
        // As a sub-component, secondComponent depends on an object being present in the service. This
        // will be created by firstComponent, which will reside on the same page.           
        this.someVals = factory.vals;
    }
});

Factory Service

angular.
module('simple').
factory('factory', function() {
    var data = {};
    data.vals = {};
    data.changeData = function() {
        data.vals = {
            "a": 11,
            "b": 22,
            "c": 33
        };
    };
    return data;
});

I would like to see component 2 and component 1 referencing the same data after it is changed by component 1:

Component 2

Component 1

Instead I see:

Component 2

Component 1

Is there a technique I should use for instantiating objects in one component and then sharing it with another component that might happen to live on the same page and not have the component order on the page matter? The timing clearly matters in this example. If I reverse the order of my components, it works fine. But graphically I need my second component to go first and it doesn't make sense instantiating my object in the service from within the second component as it is supposed to be a purely presentational component relying on service state data. Again, I thought two-way data binding would detect when the first component changes the object in the service, but it doesn't seem to work that way.

P.S. I'm fairly new to AngularJS. I have read a lot of great articles and watched some great videos; your suggestions on reference material or tutorials are most welcome!

Upvotes: 1

Views: 153

Answers (1)

Harsha ANS
Harsha ANS

Reputation: 136

As per your requirement you need to call the service again in . By means of $emit you can send a message to second component from first component and there by call the service function again. First Component

factory.changeData();
notify();
this.someVals = factory.vals;
function notify(){
 $rootScope.$broadcast('notifier', message);
}

Second Component

function updateVals() {
 this.someVals = factory.vals;
}
$scope.$on('notifier', updateVals)

Upvotes: 1

Related Questions