20

I want to navigate to another state/screen and pass a simple json object to this next screen.

I have the following:

var benefit = { "x": "y"};
$state.go('pages.claimed', { 'benefit': benefit });

My state looks like this:

.state('pages.claimed', {
  url: '/claimed',
  views: {
    'page': {
      templateUrl: 'templates/pages/claimed.html'
    }
  }
})

I can't however access the "benefit" object/parameter in the pages.claimed view. I'm using the ionic framework based on angular.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Jorre
  • 17,273
  • 32
  • 100
  • 145
  • 2
    change your url to `url: '/claimed?benefit'`, and get `$stateParams.benefit ` in controller – Umidbek Aug 04 '14 at 10:09
  • Thanks, is it a good idea to pass an object through the url? My url looks quirky like this: claimed?benefit=%5Bobject%20Object%5D – Jorre Aug 04 '14 at 10:17
  • If there no other option to pass values (e.g. as query parameter `?x=1&b=2`, or url parameter `yoururl/1/2`), you can use Base64 encoding for your json string https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding – Umidbek Aug 04 '14 at 10:23

5 Answers5

15

Parse object to json:

var benefit = angular.toJson({ "x": "y"});

Define variable in state params:

.state('pages.claimed', {
   url: '/claimed?params',
   views: {
     'page': {
       templateUrl: 'templates/pages/claimed.html'
     }
   }
})

Access to variable from controller via $stateParams:

var benefit = angular.fromJson($stateParams.benefit);

Here full doc

Edit:

There are several ways to pass an object to controller from url:

Via query params:

define options url: '/yoururl?a&b&c',

pass variables yoururl?a=1&b=2&c=3

Via url params:

define options url: '/yoururl/:a/:b/:c',

pass variables yoururl/1/2/3

For more complicated situations you can parse your object to json string and encode it with base64

Object: { a:1, b:2, c:3 } JSON String: {"a":1,"b":2,"c":3} Base64 Encoded string: eyJhIjoxLCJiIjoyLCJjIjozfQ==

define options url: '/yoururl?params'

pass variables yoururl?params=eyJhIjoxLCJiIjoyLCJjIjozfQ==

More info about base64

Ajay Barot
  • 1,681
  • 1
  • 21
  • 37
Umidbek
  • 1,504
  • 12
  • 26
  • Thanks, that passes the data indeed. Can you tell me if it's a good idea to pass objects like that in the url? My app won't show the url so that's not really a (bookmarking) issue – Jorre Aug 04 '14 at 10:20
  • If this the only way to notify your controller, yes, this is common solution. – Umidbek Aug 04 '14 at 11:10
  • The answer from @Chinthaka Suren Fernando is a more straightforward and does not require the dev to manually parse and rebuild the object, plus the URL displayed to the client is much cleaner – Gabe Gates Nov 27 '18 at 15:36
9

$state.go should be corrected like this

var benefit = { "x": "y"};
$state.go('pages.claimed', { benefit: benefit });

.state should be like this

.state('pages.claimed', {
  url: '/claimed',
  params: { benefit: null },
  views: {
    'page': {
      templateUrl: 'templates/pages/claimed.html'
    }
  }
})

Catch the passed object as follows in the next controller

(function () {
    'use strict';

    angular.module('YourAppName').controller('ControllerName', ['$stateParams', ControllerName]);

    function ControllerName($stateParams) {
  var vm = this;
        vm.variableToBind = $stateParams.benefit;
    };
})();
Gabe Gates
  • 902
  • 1
  • 14
  • 19
4

Very clean solution:

app.js:

$stateProvider.state('users', {
    url: '/users',
    controller: 'UsersCtrl',
    params: { obj: null }
})

controllers.js

function UserCtrl($stateParams) {
    console.log($stateParams);
}

Then from any other controller:

$state.go('users', {obj:yourObj});
askilondz
  • 3,264
  • 2
  • 28
  • 40
3

I'm not sure what you're application is doing, but if you need to share information between two controllers you should be using some sort of service, not passing a bunch of data through the URL. The URL is to pass parameters around to identify the state, not be the means of data transportation.

You're probably going to want a factory of some sort. Here's a little benefit registration service... assuming underscore.

.factory('benefitsService', ['_', function(_){
    function BenefitsService(){
        this.benefits = [{
           id: 'benefit1',
           x: 100,
           y: 200
        },{
           id: 'benefit2',
           x: 200, 
           y: 300
        }];
    }

    // use this to register new benefits from a controller, other factory, wherever.
    BenefitsService.prototype.addBenefit = function(benefit){
        this.benefits.push(benefits);
    }

    BenefitsService.prototype.findById = function(id){
        return _.findWhere(this.benefits, {id: id});
    }

    return new BenefitsService();
}]);


.run(['benefitsService', function(benefitsService){
     // we're going to register another benefit here to show usage....
     benefitsService.addBenefit({
        id: 'addedBenefit', 
        x: 2000, 
        y: 4000
     });
}])

Then you just pass the id through the URL to something normal "/url/:id" .controller('firstController', ['$state', function($state){ $state.go('stateId', { id: 'addedBenefit' }); });

// and use your injected service to find your data.

.controller('secondController', ['$state', 'benefitService', function($state, benefitService){
    var benefit = benefitService.findById($state.params.id); 
    // and you're home!
}]);

This way you don't end up with a bunch of cruft inside of your URL, only what you need to identify state. You've also obfuscated the storage mechanism, so you can use an object, local storage, or any synchronous storage mechanism you'd like.

You also have a service you can inject and use anywhere else through your application.

sammysounder
  • 316
  • 2
  • 8
  • Maybe helpful to op's specific situation, but doesn't answer their question. This would be better served as a comment. – Josh Noe May 18 '15 at 21:16
1

Looks like you missed parameter 'data' in your state:

.state('pages.claimed', {
    url: '/claimed',
    views: {
      'page': {
        templateUrl: 'templates/pages/claimed.html'
      }
    },
    data: {
      benefit: {}
    }
  })

Here is description from documentation

punov
  • 798
  • 7
  • 16