Mohsin Patel
Mohsin Patel

Reputation: 226

How do I share data across controllers in AngularJS?

I am doing a project that uses AngularJS. I have created partial pages where each page has its own, different controller.

Site Structure

/ProjectRoot
    /css
    /js
        angular.js
        jquery.js


    /partials
        login.html
        page1.html

    index.html

index.html

<!DOCTYPE html>
<html ng-app="demoapp" >
<head>
    scripts
</head>
<body ng-controller="maincontroller">   
     <ng-view></ng-view>
</body>
</html>

login.html

<div class="main-page" ng-controller="logincontroller">
    --code---
</div>

So the full login page is rendered as:

<!DOCTYPE html>
    <html ng-app="demoapp" >
    <head>
        scripts
    </head>
    <body ng-controller="maincontroller">   
         <div class="main-page" ng-controller="logincontroller">
            --code---
         </div>
    </body>
    </html>

I need to share data between the controllers. I tried using $scope.$parent.variablename but when I refresh page1.html it contains a blank value.

My questions are:

  1. How do I create global variables which I can use throughout the project, that is with all partial pages and their controllers (perhaps $rootScope)?

  2. Is the use of a cache is better option or not? (security concern)

Upvotes: 4

Views: 599

Answers (1)

biofractal
biofractal

Reputation: 19123

To share state between controllers you should use an Angular service. Services are easy to define and use (see example below) and since they are singletons they are a great place to store shared state information. No need for caches or anything complex.

But then you also said:

I tried using $scope.$parent.variablename but when I refresh page1.html it contains a blank value.

Refreshing an Angular app is always going to be a problem.

This is because your typical Angular app is a Single Page Application (SPA). Your state information persists only as long as the lifetime of the app, which for an SPA is the lifetime of the page. Thus, if you refresh the page then you restart the application and all your state information is lost.

To solve this problem you can use sessionStorage. This technology is well supported across browsers and allows you to persist your state data between page refreshes. This is especially important in Angular apps because they should always gracefully support the user refreshing the page (which includes clicking on the back and forward buttons).

You can combine all this into a simple service that persists its data into sessionStorage. This gives you state data that is shared between controllers and persisted between page refreshes.

Here is an example (in coffeescript) that stores a state datum called userToken:

Service

angular
.module 'app'
.service 'storageService', StorageService

class StorageService

    setStorage:(key, value)->
        json =  if value is undefined then null else JSON.stringify value
        sessionStorage.setItem key, json

    getStorage:(key)->
        JSON.parse sessionStorage.getItem key

    userToken:(value=null)->
        if value is null
            @getStorage 'userToken'
        else
            @setStorage 'userToken', value

You can add as many data values to this service as you like, you can even store complex objects

Once you have defined a service you can use Angular's dependency injection to easily get hold of the service instance. Here are a couple of example controllers that show the storageService being injected and used:

Controller

angular
.module 'app'

.controller 'logincontroller', ($scope, storageService)->
    $scope.setUserToken = (token)-> storageService.userToken(token)

.controller 'maincontroller', ($scope, storageService)->
    $scope.userToken = storageService.userToken()

Upvotes: 4

Related Questions