r3plica
r3plica

Reputation: 13367

AngularJS Shared service between controllers

I have an issue with my shared service. I created a service that looks like this:

.factory('ConfiguratorService', ['$q', 'ColourService', 'Moltin', 'ArrayService', function ($q, colourService, moltin, arrayService) {

    // Gets a new kit or gets from the session
    var getKit = function () {

        // Create the base model
        var model = {
            name: '',

            garments: [],
            totalPrice: 0,

            colour1: '',
            colour2: '',
            colour3: '',

            team: {
                name: '',
                sport: '',

                colour1: '',
                colour2: '',
                colour3: ''
            }
        };

        // If we have our model in the session, then return that otherwise use the base model
        return sessionStorage.designer ? angular.fromJson(sessionStorage.designer) : model;
    };

    // Declare our service
    var service = {

        // Define our properties
        selectedColours: [],
        selectedLeisureColours: [],
        kit: getKit(),

        // Init
        init: function (slug) {

            // Get our Sport
            return service.getSport(slug).then(function (response) {

                // If we get our sport, get our colours
                return colourService.list();

            // If we get our colours
            }).then(function (response) {

                // Add them to our service
                service.colours = response;
            });
        },

        // Gets our sport by it's slug
        getSport: function (slug) {

            // Defer our promise
            var deferred = $q.defer();

            // If we have a slug 
            if (slug) {

                // Return the category
                moltin.categories.get(slug).then(function (response) {

                    // Assign our response to the service
                    service.sport = response;

                    // If we have a response
                    if (response) {

                        // Assign our sport to our team
                        service.kit.team.sport = response.slug;
                    }

                    // Resolve our promise
                    deferred.resolve(response);
                });

            // Otherise, nothing was supplied
            } else {

                // Resolve anyway
                deferred.resolve();
            }

            // Return our promise
            return deferred.promise;
        },

        // Saves the session to the session storage
        saveSession: function () {

            // Store our model in the session
            sessionStorage.designer = angular.toJson(service.kit);
        },

        // Clears the session
        clearSession: function () {

            // Remove our model from the session
            sessionStorage.removeItem('designer');
        }
    };

    // Return our service
    return service;
}])

I have a controller that invokes the init function and that all works fine. The problem I have, is that in the next view, the controller (even though when I console log out the service shows everything) does not assign the colours to the scope.

My controller looks like this:

.controller('DesignerTeamController', ['PageTitle', 'ConfiguratorService', 'ColourService', function (pageTitle, configuratorService, colourService) {
    var self = this;

    pageTitle.setTitle('Kudos Sports - Choose your team');

    console.log(configuratorService);

    // Assign our models
    self.colours = configuratorService.colours;
    self.range = [1, 2, 3];

    // Set our colours
    self.setColour = configuratorService.setColour;
}])

The console.log(configuratorService); actually shows configuratorService.colours as an array with 30 items in it. But, if I console.log(self.colours) I get undefined.

Does anyone know why?

Upvotes: 0

Views: 211

Answers (1)

charlietfl
charlietfl

Reputation: 171669

The problem occurs because there is no colours property in the service object until the getSport(slug) callbacks do the assign.

Two ways you could manage this would be:

1) assign the property as an empty array that gets updated within the callback. Then the property won't be undefined in controller and because it is an array a reference will be created

var service = {
    colours:[]
    .....
}

Don't break the array reference in the callback , just update the array

// If we get our colours
}).then(function (response) {
     // Add them to our service
     service.colours.concat( response);
});

2) Another approach is assign the whole service object to a variable in controller:

// Assign our models
self.configModel = configuratorService;

Then in the view you can add the colours property to your configModel object:

ng-if="vm.configModel.colours.length"

Upvotes: 4

Related Questions