67

I am an AngularJS starter. I am trying to send data from :

  • Page A : Van Listing page

    to

  • Page B: Van Update page.

When user click the update link for a van, I am invoking a controller and retrieving the van details in the controller. But, I cannot assign the van details to the Page B ( Van Update Page) using the same controller... Error "Cannot set property 'vanNumber' of undefined"

*** Page A: Van List ****

<form name="listVanForm" >
   <table>
   <tr> <td ng-controller="VanUpdateCtrl"><a href="#/van-update" ng-click="prePopulateForm(row.members.vanNumber.value )" class="btn btn-small btn-primary">update</a></td> </tr>
   </table>
</form>

*** Page B: Van Update ****

  <div class="container">
        <h2>Edit Van </h2>
    
        <form name="updateVanForm" novalidate="novalidate" class="form-horizontal" ng-submit="updateCard(formData)">
            <div class="control-group">
                <label class="control-label" >Van Number:</label>
    
                <div class="controls">
                    <input type="text" id="vanNumber" ng-model="formData.vanNumber" placeholder=""/>
                </div>
            </div>
        </form>
     </div>

*** VanUpdateCtrl **

   app.controller('VanUpdateCtrl', ['$scope', 'VanUpdateFactory', '$location',
                                      function ($scope, VanUpdateFactory, $location) {
    
        //callback for ng-init 'populateDD':    
        $scope.prePopulateForm = function (cardNoParam m) {
            
            alert('cardNo = '+cardNoParam);
            
            $scope.formData.cardNumber=cardNoParam;}
    }
    
So, $scope.formData.cardNumber OR $scope.formData in the destination page is not recognised.
7
  • How many controllers you got on the page? Maybe I'm understanding wrong your scenario, could you post all the involved controllers. Commented Mar 14, 2014 at 16:22
  • So I'm guessing the route #/van-update has VanUpdateCtrl associated to it in the $routeProvider, right? Commented Mar 14, 2014 at 16:41
  • 3
    Just so you know every time a controller gets referenced, either via ng-controller or by associating it to a route, it's a new instance of that controller. You can't share the controller in terms of using the same $scope between pages. Commented Mar 14, 2014 at 16:44
  • Yes and that works fine. Problem is when the Van Update screen is displayed first time, I want to prepopulate it with details from the van listing using the same controller. I can handle the form submission successful after the users has done the changes. Its just prepopulating the form that is an issue. Commented Mar 14, 2014 at 16:44
  • Does, that mean I have to use 2 controllers and one service.Set the van details in a service using one controller and retrieve in the second controller. May using the ng-init function on the update details page. Commented Mar 14, 2014 at 16:53

4 Answers 4

126

You need to create a service to be able to share data between controllers.

app.factory('myService', function() {
 var savedData = {}
 function set(data) {
   savedData = data;
 }
 function get() {
  return savedData;
 }

 return {
  set: set,
  get: get
 }

});

In your controller A:

myService.set(yourSharedData);

In your controller B:

$scope.desiredLocation = myService.get();

Remember to inject myService in the controllers by passing it as a parameter.

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

16 Comments

Didn't work for me. On the next page, the service seems to be re-created and get() returns empty.
@AlexisGamarra if you read the comments, you will understand that you can't have the same controller in two different pages, each controller is a new instance.
It works great. But if I refresh the second page by pressing ctrl + f5, the services resets and the page becomes empty due to this. How do you cache the last set data so the last data is not lost when the second page with Controller B is refreshed?
@blackops_programmer you could use $cookies or localStorage.
Yes, use sessionStorage.setItem('key', 'value'); in your service to store it and sessionStorage.getItem('key') to retrieve it.
|
8

What you should do is create a service to share data between controllers.

Nice tutorial https://www.youtube.com/watch?v=HXpHV5gWgyk

1 Comment

I'd like to clarify - would this work if I open the second page in a new tab? I'm going to re-try, may be in my original tests I didn't implement it correctly as it didn't work for me
8

If you only need to share data between views/scopes/controllers, the easiest way is to store it in $rootScope. However, if you need a shared function, it is better to define a service to do that.

5 Comments

@YangZang. Thanks for sharing this option. To emphasize. You can store data to the $rootScope, then retrieve it from another view. However, as with any quick solution that uses the root/global scope, there's almost always a better solution. The Angular solution to this problem would be to pass your data in via a shared service.
depending on the data. This could be terrible if you setting var, it would cause digest to go over rootScope
Using $rootScope to share data between pages is a terrible idea. Yes, it's the easiest way to do it, but it's also the way that will ruin you the most in the future. It's global data, which can come back to bite you when that data starts getting accidentally mutated by a third page that doesn't know that variable is already defined. It pollutes $rootScope, making digest cycles slower. There are so many reasons to never use $rootScope for sharing data, just like there are so many reasons to never use global variables in traditional programming languages.
@iamtheddrman great point about polluting the rootScope. I 100% agree with you, but do you have any references for how this would cause digest cycles to become slower?
Sure: airpair.com/angularjs/posts/… medium.com/developers-writing/… Some of the performance loss also comes from the likelihood of watchers triggering other watchers in a digest cycle, making it take longer to settle back down when an outside force acts on it. Smaller $rootScope and proper use of services and controllers alleviates this issue, yielding a MUCH faster application.
-1
app.factory('persistObject', function () {

        var persistObject = [];

        function set(objectName, data) {
            persistObject[objectName] = data;
        }
        function get(objectName) {
            return persistObject[objectName];
        }

        return {
            set: set,
            get: get
        }
    });

Fill it with data like this

persistObject.set('objectName', data); 

Get the object data like this

persistObject.get('objectName'); 

1 Comment

More like you reposted an answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.