Jorge Rodríguez
Jorge Rodríguez

Reputation: 427

Angular - pass info from array from one controller to another

I'm having a little problem trying to pass a service within controllers.

What I'm trying to do is a shopping cart, I have a list of items and when I hit a button, those items get added to the cart, then I want to list those items in the cart in a separate page using a separate controller, so I'm trying to use a factory for the cart, but I don't know if you can set a factory object within a controller.

Here's my code, hope you can point me in the right direction.

var app = angular.module("Shop", []);

app.factory('DataService', function () {
var cart = [];
var set = function (data) {
    cart = data;
}
var get = function () {
    return cart;
}
});

app.controller("catalogController", function ($scope, $http) {
$scope.bookStore = {
    selected: {},
    books: null
};
$scope.cart = [];
$http.get("json/books.json")
    .success(function (data) {
        console.log(data);
        $scope.bookStore.books = data;
    })
    .error(function (err) {

    });

$scope.addToCart = function (book) {
    var found = false;
    $scope.cart.forEach(function (item) {
        if (item.id === book.id) {
            item.quantity++;
            found = true;
        }
    });
    if (!found) {
        $scope.cart.push(angular.extend({
            quantity: 1
        }, book));
    }
};

$scope.removeFromCart = function (item) {
    var index = $scope.cart.indexOf(item);
    $scope.cart.splice(index, 1);
};

$scope.getCartPrice = function () {
    var total = 0;
    $scope.cart.forEach(function (product) {
        total += product.price * product.quantity;
    });
    return total;
};
});

app.controller("checkoutController", function ($scope, DataService) {
$scope.cart = DataService;
});

Upvotes: 0

Views: 1314

Answers (2)

IsraGab
IsraGab

Reputation: 5185

You should do something like this:

A service is a singleton in angular js, that's mean you only have one instance of this class in your app.

var app = angular.module("Shop", []);

    app.factory('DataService', function ($http) { // usualy your service is the one which call your API (not your controller)
    var cart = null; // the cart array is set in the instance of the class as private

    return{ // here you declare all the functions you want to call from outside (your controllers)
             set : function (data) {
                 cart = data;
             },
              get: function(){
               return cart;
             },
             getFromAPI = function () { // the code you have in your controller should goes here
                 return $http.get("json/books.json")
                       .success(function (data) {
                           console.log(data);
                        cart = data; //now you set you cart variable
                       })
                      .error(function (err) {

                   });
             }, 
        });

Then in your controllers:

app.controller("catalogController", function ($scope, DataService) { // include your service as a dependency
$scope.bookStore = {
    selected: {},
    books: null
};
$scope.cartInCatalogController = DataService.get(); // it will set the value of cart that's in your service to your controller's scope
if(!$scope.cartInCatalogController) {// if it's null so call the API
      DataService.getFromAPI()// this function should return a promise
        .success(function(data){// so call the success function
             $scope.cartInCatalogController = data;
         })
        .error(function(error){
           // do something here if you want
      });
});

You can do the same in your other controller. About the addToCard function and other stuff I let you find it by yourself.

You can start from here :)

Upvotes: 1

JanP
JanP

Reputation: 1581

Change things a bit to something like:

app.factory('DataService', function () {
    var cart = [];

    return {
        set: function (data) {
            cart = data;
        },
        get: function () {
            return cart;
        },
        add: function (item) {
            cart.push(item);
        }
     }
});

...

app.controller("checkoutController", function ($scope, DataService) {
    $scope.cart = DataService.get();
});

And then move the $http.get method and all the operations on the card in the other controller to functions in the factory and declare them on the same way as the above Dataservice.get()

Upvotes: 1

Related Questions