Renaud is Not Bill Gates
Renaud is Not Bill Gates

Reputation: 2074

using url parameters in angularjs

I'm creating an angularjs application, and I have my app.js as following :

var capValueRecruitApp = angular.module('capValueRecruitApp', ['ui.router']);

capValueRecruitApp.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('home', {
      url: '/home',
      templateUrl: 'views/home.html',
      controller: 'offresController'
    })
    .state('offres', {
      url: '/offres',
      templateUrl: 'views/offres.html',
      controller: 'offresController'
    })
    .state('offres.detail', {
      url: '/offres/:id',
      templateUrl: 'views/offres.detail.html',
      controller: 'offresController'
    });
  $urlRouterProvider.otherwise('/home');
});

when I enter to #/offres I get a list of offers in the offres.html page, and I want when I enter to #/offres/5 to get the entry with the key 5 in the offres.detail.html.

in the ui route documentation I solved that with using /offres/:id and in the controller I test the existence of the parameter I passed to the url as following:

capValueRecruitApp.controller('offresController', function($scope, offresFactory, $stateParams) {
  console.log($stateParam.id);
  offresFactory.getList().then(function(list) {
    $scope.offres = list.data;
    console.log($scope.offres);
  }, function(msg) {
    alert(msg);
  });

});

but when I enter to #/offres/5 the application routes me to the default route with is /home.

How can I solve that ?

Edit :

After changes I made as following :

.state('offres.detail', {
      url: '/:id',
      templateUrl: 'views/offres.detail.html',
      controller: 'offresController',
      resolve: {
        offresDetail: ['offresFactory', '$stateProvider', function(offresFactory, $stateProvider) {
          return offresFactory.getOffresDetail($stateProvider.id);
        }]
      }
    })

and in controller :

capValueRecruitApp.controller('offresController', function($scope, offresFactory, offresDetail) {
  offresFactory.getList().then(function(list) {
    console.log(offresDetail.data);
    $scope.offres = list.data;
    console.log($scope.offres);
  }, function(msg) {
    alert(msg);
  });


});

and my factory :

capValueRecruitApp.factory('offresFactory', function($http) {
    var factory = {
        getList: function() {
            return $http.get('http://localhost:8080/offres')
                .then(function(response) {

            return response;

                }, function(error) {
                    return 'There was an error getting data';
                });
        },
    getOffresDetail: function(id) {
      return $http.get('http://localhost:8080/offres/'+id)
        .then(function(response) {
          console.log(id);
          return response;

        }, function(error) {
          return 'There was an error getting data';
        });
    }
    };
    return factory;
});

as you can see I have two console.log one in the factory to test the id and the other to test the offresDetail.data but I cant see any message in the console and the view didn't injected and neither I can see some error message.

Upvotes: 1

Views: 39

Answers (1)

Bata
Bata

Reputation: 651

When you define a child state, a url to it is relative to the parent state. So in your case you defined this state: "/offres/offres/5". So just change the child state's url to be relative to the parent state, like this:

.state('offres.detail', {
    url: '/:id',  // <-- change to this
    templateUrl: 'views/offres.detail.html',
    controller: 'offresController'
});

I would also suggest that you resolve the necessary data for your state controller. Example:

.state('offres.detail', {
    url: '/:id',
    templateUrl: 'views/offres.detail.html',
    controller: 'offresController',
    resolve: {
        offresDetail: ['offresFactory', '$stateProvider', function(offresFactory, $stateProvider) {
            return offresFactory.getOffresDetail($stateProvider.id);
        }]
    }
});

and the in the controller just pass the resolved data:

capValueRecruitApp.controller('offresController', function($scope, offresDetail) {
    $scope.offresDetail = offresDetail.data;
});

You should handle the error message in your service.

Upvotes: 1

Related Questions