AngularJS : Pass data from one view to another with in same controller

8.3k views Asked by At

Summary :

I have a form in view(first) of my angular application and on success response from the ajax call on submit it redirects the user to the view(second). There is only one controller for the application(for all view). Here, user can enter the fields in the form from the view(first) which should get displayed on the view(second) & again there is a form in the view(second) where user can enter the fields in the form which should get displayed on the view(third).

As all the views(first,second,third) sharing the same controller function.I created one service to set & get the data from one view to another and use this service across the application to send the data from one view to another view sharing the same controller.

Problem statement :

I am not able to store each form data in a separate variable as i am getting the data from the same service across the whole application.

Diagram :

enter image description here

As services are singletons in angular. So they won't be recreated when you go to another page.So, when i call a dataService.setData() method from the controller it removes the previous stored data in the service and updated with new one which creates a problem for me. I want to store all views data separately instead of override with each other.

4

There are 4 answers

0
lealceldeiro On BEST ANSWER

In you controller create some keys for each different view, lets say:

this.keys = {
    "firstView": "firstView",
    "secondView": "secondView",
    "thirdView": "thirdView",
}

and when you call the setData method, receive the data to be stored and the key, lets say

dataService.setData(data, keys.firstView)

and update your getData so you can choose which data you want to get like this

dataService.getData(keys.firstView)

Now your dataService must be like this:

angular.module('app').service('dataService', function() {
    var s = {};
    function setData(data, key){
        s[key] = data;
    }

    function getData(key){
        return s[key];
    }
})
3
Manu Obre On

Use a factory with a 'stored' value like this. Add an Identifier per each View, so it will work like a Hash Table.

.factory('storeValue', function() {
    var valueStored= {};
    return {
        getValue: function(viewId) {
            return valueStored[viewId];
        },
        setValue: function(newValue,viewId) {
            valueStored[viewId] = newValue
        }
        deleteOrder: function(viewId) {
            delete valueStored[viewId];
        }
    };
})

Suppose this is the controller for one of your Views, and has as dependency the above factory

$scope.setData = function(){
    storeValue.setValue('value for First View', $state.current.name);
}

$scope.getData = function(){
    storeValue.getValue($state.current.name); // This will return the String 'value for First View'
}

So, You will set a value and an Identifier for the first View. The $state object which represents the current View, will work as an Id of the corresponding View. And you could do the same for the rest of your view, without loosing data.

1
Ghazanfar Khan On

The easiest and smartest solution is to use parent child relationship of scope in AngularJS. It is more powerfull then using a service for storing view data.

Suppose you have a parent controller. Under parent controller you have child controllers like firstStepCtrl,secondStepCtrl,thirdStepCtrl and so on.The data in parent controller will be shared across child controllers. So if you set a model on parent controller and bind that model in child controllers it will remain stored in parent controller while navigating between steps.

Example code

$scope.model={
   firstStep:{},
   SecondStep:{},
   thirdStep:{}
   currentStep:0,
   steps:['step1','step2','step3']
}



<div ng-controller="parentCtrl">

<div ng-include="model.steps[currentStep]">
</div>

</div>


<script type="text/ng-template" id="step1">
<div ng-controller="firstStepCtrl">
<h1>Step 1</h1>
<input type"text" ng-model="model.firstStep.name"/>
</div>
</script>

<script type="text/ng-template" id="step2">
<div ng-controller="secondStepCtrl">
<h1>Step 2</h1>
<input type"text" ng-model="model.SecondStep.name"/>
</div>
</script>


<script type="text/ng-template" id="step3">
<div ng-controller="thirdStepCtrl">
<h1>Step 3</h1>
<input type"text" ng-model="model.thirdStep.name"/>
</div>
</script>

As you can see every step model is saved in parent controller and you can access it easily. I ave used ng-include instead of ui-router.You can increment decrement currentStep for navigating.

Hope it helps.

1
rrd On

If you are using ui-router you can use the params to pass data on from one state to another state.

So for example your three states (plus one abstract parent):

$stateProvider.state('parent', {
  abstract: true,
  param: {
    propertyOne: null,
    propertyTwo: null
  }
})
.state('parent.first', {
  controller: YourController,
  params: {
    propertyOne: null,
    propertyTwo: null
  }
})
...repeat for all the other states you want with the params

Then when submit() gets fired and you can call the $state.go you can pass along the variables:

$state.go("seconds", { propertyOne: 'one', propertyTwo: 'two' }, { inherit:false });