Search code examples
javascriptangularjsonsen-ui

Accessing a service from a controller in another file in AngularJS


I have a cross platform enterprise app built using Onsen UI and AngularJS.

The app has grown fast and so I have decided to split my main app.js file into separate files. Up to now each page has had its own controller and all controllers were in the one app.js file.

I also have a service defined in my app.js where I store values like username etc. for sharing between the controllers. I need to store these during the app cycle as all values entered on all the pages are sent to the server at the end of the user interaction.

I have successfully split the controllers into their separate files but I am having difficulty moving the services to its own file e.g. sharedProperties.js.

My "new" app.js (abbreviated) looks as follows:

// Create the module that deals with the controllers
var app = angular.module("myApp", ['onsen', 'loginController', 'registerController']);

Then I create each controller in its own file e.g. login.js as follows:

// Get the main app.js module
var login = angular.module("loginController", []);
login.controller("LoginController", function($scope, $http)
{
    // Need to get and set values from/to sharedProperties here
});

The different .js files are then declared in index.html and all this seems to be working OK.

I have tried to create the service sharedProperties in its own file e.g. sharedProperties.js in the same fashion as below, but this does not work.

// Get the main app.js module
var shared = angular.module("sharedProperties", []);
shared.service("SharedProperties", function()
{
    var username = "";   

    return {
        // Get and set the userName
        getUserName: function()
        {
            return userName;
        },
        setUserName: function(value)
        {
            userName = value;
        }
    }
});

I have tried adding the sharedProperties to my modules but neither worked. I have tried adding it to my main app as below:

// Create the module that deals with the controllers
var app = angular.module("myApp", ['onsen', 'sharedProperties', 'loginController', 'registerController']);

As well as to the function() of the individual controllers:

var login = angular.module("loginController", []);
login.controller("LoginController", function($scope, $http, sharedProperties)
{
    // Need to get and set values from/to sharedProperties here
});

But neither of those work. How do I make my sharedProperties from the new file available to all my controllers?

Also, how do I call my getter and setters then. When all controllers and service were in my original app.js file, I would create the controller, add sharedProperties to the function() and then call my getter and setters e.g.

app.controller("LoginController", function($scope, $http, sharedProperties)
{
    sharedProperties.setUserName(someValue);
    sharedProperties.getUserName();
});

Or is there a better way of doing this? As I mentioned, I have to split the app.js file into separate files as the app is growing quite large and is getting difficult to manage. And for reasons outside of my control the app will grow even bigger over time.


Solution

  • You have to inject the module 'sharedProperties' into the module you're looking to use it in.

    By doing this it makes the module aware of everything inside 'sharedProperties'. So instead of injecting 'sharedProperties' into controllers and other services, you need to inject the actual service. like so:

        var app = angular.module("myApp", ['onsen', 'sharedProperties', 'loginController', 'registerController']);
    
    
        var login = angular.module("loginController", []);
        login.controller("LoginController", function($scope, $http, SharedProperties)
        {
        // Need to get and set values from/to sharedProperties here
        });
    

    then from there, calling any functions you bound to that service is as simple as

    SharedProperties.someFunction();
    SharedProperties.someOtherFunction();
    

    Another note: I would recommend long hand injection

    login.controller("loginController", ['$scope','$http', 'SharedProperties', function($scope, $http, SharedProperties){
        //code in here
    }]);
    

    This is for if you are ever going to minify or uglify your code.