I am trying to transfer data between controllers.
So this is my first controller that fetches data first when page loads using http-
function GetController($scope, $http) {
$http.defaults.useXDomain = true;
$http({
method: 'POST', url: serviceUrl + '/GetProductsByCategoryOrName', headers: {
'Authorization': apiKey
},
data: { "query": "grocery", "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" }
}).then(function successCallback(response) {
$scope.products = response.data;
}).then(function errorCallback(error) {
})
}
the view looks like-
<div ng-controller="GetController">
<div class="mdl-cell" ng-repeat="product in products">
<img src="{{product.largeImage}}" />
<div class="mdl-card__title">
<h6 class="mdl-card__title-text">{{product.name}}</h6>
</div>
</div>
</div>
</div>
Where now my need is to rebind this HTML with the same request but different parameters. So I created another controller for this job-
function searchProductsController($scope, $http) {
$http.defaults.useXDomain = true;
$scope.searchText = "";
$scope.submit = function () {
$http({
method: 'POST', url: serviceUrl + '/GetProductsByCategoryOrName', headers: {
'Authorization': apiKey
},
data: { "query": $scope.searchText, "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" }
}).then(function successCallback(response) {
$scope.products = response.data; //how to bind this with GetController's $scope.products??
}).then(function errorCallback(error) {
});
}
};
What is needed-
I want to bind $scope.products
of searchProductsController
to GetController's
$scope.products
so that it renders in view.
I don't have any idea how to do this at the moment as I am very new to angular.
However, I've given a try to create service for transferring purpose but don't really have idea how to integrate it with it.
Edit-
I've edited controller methods as @Varkal suggested using service, Still couldn't get the problem resolved.
var app = angular.module("productsApp", [])
.service("serviceProvider", function ($http) {
this.getDatas = function getDatas(data) {
return $http({
method: 'POST', url: serviceUrl + '/GetProductsByCategoryOrName', headers: {
'Authorization': apiKey
},
data: data
})
}
return this
});
function GetController($scope, serviceProvider) {
var data = { "query": "grocery", "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" };
serviceProvider.getDatas(data).then(function (response) {
$scope.products = response.data.data;
});
}
function searchProductsController($scope, serviceProvider) {
var data = { "query": $scope.searchText, "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" };
$scope.submit = function () {
serviceProvider.getDatas(data).then(function (response) {
console.log(response.data.data);
$scope.products = response.data.data;
});
}
};
When you need to share things betweens controller, those things should be in a service
For example :
angular.service("datasService", function ($http) {
this.getDatas = function getDatas() {
return $http({
method: 'POST', url: serviceUrl + '/GetProductsByCategoryOrName', headers: {
'Authorization': apiKey
},
data: { "query": "grocery", "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" }
})
}
return this
});
And in your controller :
function GetController($scope, datasService) {
datasService.getDatas().then(function(){
$scope.products = response.data
}
}
This is a very simple example : you can also store your datas in the service, so call $http only once, and add a method to refresh the product list
This is the most "Angular-ly" way of share datas between controllers, but you can also use localStorage (ngStorage can help you here)
If you have 2 views
with 2 controllers
, it is possible to share the $scope
variables(data) between controllers through services and factory.But, the $scope
variables are local to the controller itself so set the data to the service or factory to know about that particular variable.I prefer using factory, easy and smooth as butter. If you are using the service
or factory
in a separate file you need to include the file in index.html
.
app.controller('Ctrl1', function($scope, myService, $state) {
$scope.variable1 = "One";
myService.set($scope.variable1);
$state.go('app.thepagewhereyouwanttoshare'); //go to the page where you want to share that variable.
});
app.controller('Ctrl2', function($scope, myService) {
console.log("shared variable " + myService.get());
});
.factory('myService', function() {
function set(data) {
products = data;
}
function get() {
return products;
}
return {
set: set,
get: get
}
})
Also, you can use localstorage
for the purpose of sharing data.localStorage
comes with angularjs
so no need to inject any additional dependency in the controller or app.
In the controller which has to pass data:
localStorage.setItem("products",$scope.products);
In the controller where you to access data:
localStorage.getItem("products");
In your case:
function GetController($scope, $http) {
$http.defaults.useXDomain = true;
$http({
method: 'POST', url: serviceUrl + '/GetProductsByCategoryOrName', headers: {
'Authorization': apiKey
},
data: { "query": "grocery", "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" }
}).then(function successCallback(response) {
$scope.products = response.data;
localStorage.setItem("products",$scope.products);
}).then(function errorCallback(error) {
})
}
function searchProductsController($scope, $http) {
$http.defaults.useXDomain = true;
$scope.searchText = "";
$scope.submit = function () {
$http({
method: 'POST', url: serviceUrl + '/GetProductsByCategoryOrName', headers: {
'Authorization': apiKey
},
data: { "query": $scope.searchText, "categoryId": "976759", "pageIndex": 0, "sortDirection": "asc" }
}).then(function successCallback(response) {
$scope.products = response.data; //how to bind this with GetController's $scope.products??
$scope.productsFromGetController = localStorage.getItem("products");
}).then(function errorCallback(error) {
});
}
};
Using the factory
, you need to navigate to the page where you want to get the data after you set it since the data set can be overwritten by another set in another views.
FINAL UPDATE: Using service and factory
<html>
<head>
<title>Angular JS Controller</title>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<h2>AngularJS Sample Application</h2>
<div ng-app = "app" >
<div ng-controller="searchProductsController">
<input ng-model="searchText"/>
<button ng-click="setPlace(searchText)">Enter Search id</button>
</div>
<div ng-controller="GetController">
<div ng-repeat="product in products">
<h3>{{product.name}}</h3>
</div>
</div>
</div>
<script>
var app = angular.module('app', []);
app.factory("Service", function () {
var data;
function getdata() {
return data;
}
function setdata(newdata) {
data = newdata;
}
return {
getdata: getdata,
setdata: setdata,
}
}).factory("dataService",function($http){
return{
getComments:function (roomid){
if(roomid==1){
var data = [{"name":"alex","place":"kathmandu"},{"name":"god","place":"seattle"}];
return data;
}
if(roomid==2)
{
var newdata = [{"name":"newname","place":"kathmandu"},{"name":"newname2","place":"seattle"}];
return newdata;
}
}
}
});
app.controller('searchProductsController',function($scope, Service,$http,dataService) {
var data = dataService.getComments(1);
Service.setdata(data);
$scope.setPlace = function (searchText) {
var newdata = dataService.getComments(searchText);
Service.setdata(newdata);
}
})
.controller('GetController',function($scope, Service) {
$scope.$watch(function () {
return Service.getdata();
}, function (value) {
$scope.products = value;
});
})
</script>
</body>
</html>
Update regarding your unworking plunker:
It is closest i can get with the mock of your controller
:
http://plnkr.co/edit/p9qY1IIWyzYGLehsIOPr?p=preview