Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS - Sending data from a directive to a parent controller

Tags:

angularjs

I have an app where I use the ngCart directive in order to store the items added to a basket. The problem is that this directive just has the functionality of sending the information about the items added by the user, but I would need also to send some information that I would get from a form.

So in order to send it in a single object, I need first to extract the data stored in the directive to my main scope, and then merge it with the data I get from the form.

For that I need to modify the ngCart.js directive. I tried to make a service, as adviced here, but I don't get to get it working. The code I added to the directive is this

.service('ngCartData', ['ngCart', function(ngCart){

    return {
        data:ngCart;
    };

 }])

, but I get an error saying Module 'ngCart' is not available!

I'm totally new to services and factories in angular, so I don't know exactly where to look to make it work. I made a plunkr with my code (I tried modifying the ngCart.js file with the code above, but the plunkr shows the directive without any modification). I just need to be able to send the data stored in the directive in the scope ngCart so that I can listen to it in the parent controller (see the checkout section in the plunkr).

Any help would be much appreciated. Thanks!

like image 808
Joe82 Avatar asked Jun 01 '16 19:06

Joe82


3 Answers

did you load the js file like this :

 <script src="pathto/angular/angular.js"></script>
 <script src="pathto/ngCart.js"></script> or ngCart.min.js

did you load the module in your declaration module like this ? :

var myApp = angular.module('myApp',['ngCart']);
like image 169
AlainIb Avatar answered Oct 23 '22 12:10

AlainIb


You actually have this backward. You can't inject a directive into a service. You must inject the service into the main controller and into the directive so that you can use it as a bridge between the two. Services are singletons so if you modify the properties of a service those modifications will be available anywhere else it is asked for. Your service will look something like this:

.service('ngCartData', [function(){

return {
    data:[],
    addData: function(newData){
       this.data.push(newData);  
    },
    getData: function(){
       return this.data;
    }
};

}])

then in your controller and directive use the ngCartData api, which would look something like this:

 $scope.someData = ngCartData.getData();
 $scope.someFunction = function(dataToStore){
     ngCartData.addData(dataToStore);
 };
like image 23
kugyousha Avatar answered Oct 23 '22 13:10

kugyousha


You had the right idea in mind, and I'm surprised it didn't work for you.

I have edited your app in the following way (in script.js)

 app.controller('myCtrl', function($scope, ngCart, myCart) {
     $scope.names = [...];
     ...
     console.log(myCart.cart);
 })
    .factory('myCart',function(ngCart){
        return {
            cart: ngCart.$cart
        };
 })

and it logged {shipping: 30, taxRate: null, tax: null, items: Array[2]}, which I think is what you need (I added 2 items before it logged).

Notice that adding a the service is redundant; The data is accessible whenever and wherever you need. Just inject ngCart to your controller/service/etc. and the updated data will be available to you.

Therefore, the following code is equivalent:

app.controller('myCtrl', function($scope, ngCart) {
       $scope.names = [...];
       ...
       console.log(ngCart.$cart);
    });

A possible reason for the getting the error you got might be that, while editing the ngCart module, you had some sort of error (like a typo), which led to ngCart being invisible to angular.

like image 34
dror Avatar answered Oct 23 '22 14:10

dror