Ame Lives
Ame Lives

Reputation: 101

Getting one item out of ng-repeat

I have a homepage with different products and I want to display one choosen product in anouther view. (the detail view). To show the products I use ng-repeat, which iterate over an product-Array.

Now I get a single product out of the ng-repeat when cklicking an button. Then the view changes into the detail view with the choosen product. The switch of the views should go over the id, because this one is needed to make an request to my API.

At this state I tried it with $routeParams, but it'doesn't workted. Then I searched here on stackoverflow. I read that it could be scope-Problem, because I try to pass the id into an controller. (and I need that Id in another controller). When I click the Button on the homepage, nothing happents.

I hope, that somebody has an idea, how to solve this problem.

Here is a stample json file of the API:

 {
   "_id": "582ae2beda0fd7f858c109e7",
   "title": "Lorem ipsum",
    "smalldescription": "Lorem ipsum dolor sit amet,",
   "longdescription": "Lorem ipsum dolor sit ametLorem ipsum ",
   "price": "2500",
   "img": "Imagetxt"
 }

Here is my Code:

app.js

angular.module('Productportfolio', ['ngRoute'])

.config(['$routeProvider', function ($routeProvider) {

    $routeProvider
        .when('/home', {
            templateUrl: '/components/home/home.html',
            controller: 'ProductCtrl'
        })

        .when('/detail/:productId', {
            templateUrl: '/components/detail/detail.html',
            controller: 'DetailCtrl'

        .otherwise({redirectTo: '/home'});
}]);

home.html

<div ng-controller="ProductCtrl as ProductCtrl">
    <div ng-repeat="product in ProductCtrl.products ">
        <h3>{{product.title}}</h3>
            <button ng-click="loadDetail(product)">Detailansicht</button>
        </div>
    </div>

ProductCtrl.js

 angular.module('Productportfolio')

.controller('ProductCtrl', ['APIService','$location', function (APIService,$location) {

    var vm = this;
    vm.products = null;

    init();

    function init() {
        APIService.getProducts()
            .then(function (response) {
               vm.products = response.data;
            })
            .catch(function (error) {
                console.log("error at GET");
            });
    }

    vm.loadDetail = function(product){
        $location.path('/detail'+product.id);
    }
}]);

APISvc.js

angular.module('Productportfolio')

.service('APIService', ['$http', function ($http) {

    var svc = this;
    svc.root = 'http://localhost:3000/api';

    svc.API = {
        'getProducts': getProducts,
        'getProduct' : getProduct
    };
    return svc.API;

    function getProducts() {
        return $http({
            method: 'GET',
            url: svc.root + '/products'
        })
    }

    function getProduct(id){
        return $http({
            method: 'GET',
            url : svc.root +'/product/'+id
        })
    }
}]);   

DetailCtrl.js

 angular.module('Productportfolio')

.controller('DetailCtrl', ['APIService', '$routeParams', function (APIService, $routeParams) {


    var vm = this;
    vm.product = null;
    vm.productId = $routeParams.productId;

    init();

    function init() {
        APIService.getProduct(vm.productId)
            .then(function (response) {
                console.log(response);
                vm.product = response.data;
            })
            .catch(function (error) {
                console.log("error at GET");
            });
    }
}]);

Upvotes: 0

Views: 99

Answers (3)

Ame Lives
Ame Lives

Reputation: 101

Edit As @Paulson Peter said:

Remove ng-controller from div and update like below.

<div >
  <div ng-repeat="product in vm.products ">
     <h3>{{product.title}}</h3>
     <button ng-click="vm.loadDetail(product)">Detailansicht</button>
 </div>

Also in route configuration add controllerAs: 'vm'

.when('/home', {
   templateUrl: '/components/home/home.html',
   controller: 'ProductCtrl',
   controllerAs: 'vm'
 })

Like @ Aravind said:

  vm.loadDetail = function(product){
     $location.path('/detail/'+product._id); //here is the change
   }

Now I can get the product an the view changes

Upvotes: 0

Aravind
Aravind

Reputation: 41563

Replace your module file with this this

angular.module('Productportfolio', ['ngRoute'])

.config(['$routeProvider', function ($routeProvider) {

    $routeProvider
        .when('/home', {
            templateUrl: '/components/home/home.html',
            controller: 'ProductCtrl',
            controllerAs: 'ProductCtrl'  //modified as your using controller as syntax
        })

        .when('/detail/:productId', {
            templateUrl: '/components/detail/detail.html',
            controller: 'DetailCtrl',
            controllerAs : 'DetailCtrl'     //modify this also              

            //add these lines
            param:{
            productId:null
            }
        }

        .otherwise({redirectTo: '/home'});
}]);

Replace your ProductCtrl.js with this

angular.module('Productportfolio')

.controller('ProductCtrl', ['APIService','$location', function (APIService,$location) {

    var vm = this;
    vm.products = null;

    init();

    function init() {
        APIService.getProducts()
            .then(function (response) {
               vm.products = response.data;
            })
            .catch(function (error) {
                console.log("error at GET");
            });
    }

    vm.loadDetail = function(product){
        $location.path('/detail/'+product._id); // you missed a slash and the property was wrong
    }
}]);

this is the correct one $location.path('/detail/'+product._id);

Upvotes: 0

Paulson Peter
Paulson Peter

Reputation: 574

Remove ng-controller from div and update like below.

<div >
    <div ng-repeat="product in vm.products ">
        <h3>{{product.title}}</h3>
        <button ng-click="vm.loadDetail(product)">Detailansicht</button>
    </div>
</div>

Also in route configuration add controllerAs: 'vm'

.when('/home', {
    templateUrl: '/components/home/home.html',
    controller: 'ProductCtrl',
    controllerAs: 'vm'
})

Update the function like

vm.loadDetail = function(product){
    $location.path('/detail'+product['_id']);
}

Upvotes: 1

Related Questions