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
Related
I am trying to call a factory to generate token from two different controllers
1.homeCtrl
2.savingsCtrl
but m getting same token value in both places
here is my code
---factory
app.factory('tokenFactory', ['$http', function($http) {
return $http({
method: 'POST',
url: "../api/v1/getToken",
headers : {
'Content-Type':'application/json',
'X-API-KEY':'04g4g00c04ks4sokgkoosg0kwww0cww4www0kc80',
'Authorization':"Basic cGVzYXZlQXBwOkNDNTVzV0FwUW0zYWxpazlLNTcwTTFXQ1RNOUJ1TmZS"
},
data: {"grant_type":"client_credentials"}
}) .success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
----homeCtrl
app.controller('homeCtrl', ['$scope','tokenFactory', function($scope,tokenFactory){
tokenFactory.success(function(data) {
$scope.token = data;
var token=data.access_token;
}])
----savingsCtrl
app.controller('savingsCtrl', ['$scope','tokenFactory','savingsFactory', function($scope,tokenFactory,savingsFactory){
tokenFactory.success(function(data) {
$scope.token = data;
var token=data.access_token;
var userId='9c28735e-8a29-401d-b94e-6cc90a087d96';
alert(token)
$scope.getGoals=function(){
savingsFactory.getGoals(userId,token).success(function(data) {
$scope.goals = data;
var goal=$scope.goals.goalName;
alert(goal)
});
}
You should return the $http with some method not directly in factory
app.factory('tokenFactory', ['$http', function($http) {
var getToken = function(){
return $http({
method: 'POST',
url: "../api/v1/getToken",
headers : {
'Content-Type':'application/json',
'X-API-KEY':'04g4g00c04ks4sokgkoosg0kwww0cww4www0kc80',
'Authorization':"Basic cGVzYXZlQXBwOkNDNTVzV0FwUW0zYWxpazlLNTcwTTFXQ1RNOUJ1TmZS"
},
data: {"grant_type":"client_credentials"}
}) .success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}
return {
getToken : getToken
}
}]);
and then use it in controllers like this
tokenFactory.getToken().then(function (data) {
$scope.token = data.data.access_token;
var token = data.data.access_token;
alert(token);
});
I have tested this and its working
Try this:
----factory
app.factory('tokenFactory', ['$http', function($http) {
function getToken() {
$http({
method: 'POST',
url: "../api/v1/getToken",
headers : {
'Content-Type':'application/json',
'X-API-KEY':'04g4g00c04ks4sokgkoosg0kwww0cww4www0kc80',
'Authorization':"Basic cGVzYXZlQXBwOkNDNTVzV0FwUW0zYWxpazlLNTcwTTFXQ1RNOUJ1TmZS"
},
data: {"grant_type":"client_credentials"}
})
}
return {getToken: getToken}
}]);
----homeCtrl
app.controller('homeCtrl', ['$scope','tokenFactory', function($scope,tokenFactory){
tokenFactory.getToken()
.success(function(data) {
$scope.token = data;
var token=data.access_token;
}
}])
----savingsCtrl
app.controller('savingsCtrl', ['$scope','tokenFactory','savingsFactory', function($scope,tokenFactory,savingsFactory){
tokenFactory.getToken()
.success(function(data) {
$scope.token = data;
var token=data.access_token;
var userId='9c28735e-8a29-401d-b94e-6cc90a087d96';
alert(token)
$scope.getGoals=function(){
savingsFactory.getGoals(userId,token).success(function(data) {
$scope.goals = data;
var goal=$scope.goals.goalName;
alert(goal)
});
}
}])
I have created a factory to run an $http GET method. I need to add an input value to the URL pulling in the JSON but I'm having trouble passing it from the controller. I can see that the URL is being created correctly, I am just missing the "query" parameter from the form input field.
Here is my HTML block:
<input type="string" class="form-control" ng-model="getMovie.title">
Here is my factory and controller:
var app = angular.module('app', []);
app.factory("getMovie", ['$http',function($http){
var obj = {};
var url = "https://api.nytimes.com/svc/movies/v2/reviews/search.json";
obj.getMovieInfo = function(){
return $http({
url: url,
method: "GET",
params:{
query: this.title, // This is the value I need
api_key: "68094e1974e7984c256beb1653319915:3:33678189",
callback: "JSON_CALLBACK"
},
headers: {
"Content-Type" : "application/json"
}
}).then(function successCallback(response) {
this.movieReviews = response.data.results;
}, function errorCallback(response) {
console.log("Nothing to see here...");
});
}
return obj;
}]);
app.controller('moviesCtrl', ["$scope", "getMovie", function($scope, getMovie){
$scope.findMovie = function(){
getMovie.getMovieInfo().then(function(response){
$scope.results = response;
});
}
}]);
Thanks!
You can send the title as parameter to the factory method.
<input type="string" class="form-control" ng-model="title">
var app = angular.module('app', []);
app.factory("getMovie", ['$http',function($http){
var obj = {};
var url = "https://api.nytimes.com/svc/movies/v2/reviews/search.json";
obj.getMovieInfo = function(title){
return $http({
url: url,
method: "GET",
params:{
query: title, // This is the value I need
api_key: "68094e1974e7984c256beb1653319915:3:33678189",
callback: "JSON_CALLBACK"
},
headers: {
"Content-Type" : "application/json"
}
}).then(function successCallback(response) {
this.movieReviews = response.data.results;
}, function errorCallback(response) {
console.log("Nothing to see here...");
});
}
return obj;
}]);
app.controller('moviesCtrl', ["$scope", "getMovie", function($scope, getMovie){
$scope.findMovie = function() {
getMovie.getMovieInfo($scope.title).then(function(response){
$scope.results = response;
});
}
}]);
I recommend you dont use this . If you want use controllerAs syntax , use like this . You can see more in here
https://github.com/johnpapa/angular-styleguide/tree/master/a1#controllers
app.factory("getMovie", ['$http',function($http){
var vm = this
vm.getMovie ={};
And in ajax
return $http({
url: url,
method: "GET",
params:{
query: vm.getMovie, // This is the value I need
api_key: "68094e1974e7984c256beb1653319915:3:33678189",
callback: "JSON_CALLBACK"
},
headers: {
"Content-Type" : "application/json"
}
}).then(function successCallback(response) {
vm.movieReviews = response.data.results;
}, function errorCallback(response) {
console.log("Nothing to see here...");
});
}
return obj;
}]);
My app goes into infinite loop while firing $http get method inside a function
In my controller I am using POST and getting data from API after authorization and displaying it.
var app = angular.module('myApp', []);
app.controller('ctrl1', function($scope, $http) {
$http({
url: 'url',
method: "POST",
data: 'postData',
headers: {
'Authorization': 'value'
}
})
.then(function(response) {
$scope.hotels = response.data;
});
$scope.imagePath = function(id) {
console.info(id);
if (id) {
$http({
method: 'GET',
url: 'url=' + id
})
.then(function(response) {
var imgdata = response.data;
console.info(imgdata);
var imgdata1 = imgdata.data.image_name;
return "url" + imgdata1;
});
}
};
});
In my img ng-src I have to call data from another API from the key exterior_image which I am passing in my function but it goes into an infinite loop. Also I know I have to use angular forEach in imgdata1.
<div ng-controller='ctrl1'>
<select ng-options='item as item.hotel_name for item in hotels.data' ng-model='hotel'></select>
<h1>{{hotel.hotel_name}}</h1>
<p>{{hotel.hotel_description}}</p>
<img ng-src="{{imagePath(hotel.exterior_image)}}">
</div>
Try this in your Controller:
var app = angular.module('myApp', []);
app.controller('ctrl1', function ($scope, $http) {
$scope.current_Hotel = {
hotel_name: "Default Value Here",
hotel_description: "Default Value Here",
exterior_image: "Default id here",
image_url: "Default url here"
};
$http({
url: 'url',
method: "POST",
data: 'postData',
headers: {
'Authorization': 'value'
}
}).then(function (response) {
$scope.hotels = response.data;
});
$scope.selectHotel = function () {
$http({
method: 'GET',
url: 'url=' + $scope.current_Hotel.exterior_image
}).then(function (response) {
var imgdata = response.data;
var imgdata1 = imgdata.data.image_name;
$scope.current_Hotel.image_url = "url" + imgdata1;
});
};
});
and this:
<div ng-controller='ctrl1'>
<select ng-options='item as item.hotel_name for item in hotels.data' ng-model='current_Hotel'></select>
<h1>{{current_Hotel.hotel_name}}</h1>
<p>{{current_Hotel.hotel_description}}</p>
<img ng-src="{{current_Hotel.image_url}}">
</div>
I have a service function as show below
.service('ItemService', ['$http', function ($http) {
var items = [{'item_id': '1', 'item_name': 'abc'}];
return {
getItems: function () {
return items;
},
setItems: function (value) {
items = value;
}
};
}]);
This code is working fine, I want to make the items dynamic, For example
var items = $http({
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
method: 'POST',
url: 'http://localhost/app/item/get/10',
}).then(function (response) {
return response.data;
});
How should I do this ?
You service will be like this
.service('ItemService', ['$http', function($http) {
return {
getItems: function(id) {
return $http({
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
method: 'GET',
url: 'http://localhost/app/item/get/' + id,
})
},
setItems: function(items) {
return $http({
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
method: 'POST',
url: 'http://localhost/app/item/' + items,
})
}
};
}]);
And you should call it inside you controller like this
ItemService.getItems().then(function(response){
//Retrieve the data
$scope.items = response.items;
}, function(error){
//Handle the errors
})
.service('ItemService', ['$http', function ($http) {
// I want to initialize this items array before I call getItems funtion, Anyway to do the same?
var items = [{'item_id': '1', 'item_name': 'abc'}];
//Below section I want exactly same I will change items array from my controller and also I will use getItem again to get this items array agian. My getItems should only return the items array
return {
getItems: function () {
return items;
},
setItems: function (value) {
items = value;
}
};
}]);
I want to apply facebook like pagination in my application using angularjs.
how can i find on scroll end event on angularjs.
Currently i am trying with below code but it's don't work.
HTML Code
<div ng-app='myApp' ng-controller='StudController'>
<div infinite-scroll='loadMore()' infinite-scroll-distance='2'>
<div ng-repeat="stud in student.lststudent">
{{stud.rollno}}
</div>
</div>
</div>
JS Script Code
<script>
var myApp = angular.module('myApp', ['infinite-scroll']);
myApp.controller('StudController', function ($scope, $http) {
$scope.loadMore = function () {
var data = $.param({
type: "new",
});
$http({
method: 'POST',
data: data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
url: 'http://www.apiservice.com/api/StudentList/GetStudent'
})
.success(function (data) {
alert(JSON.stringify(data));
$scope.student= data;
});
};
});
</script>
API Json Response Format
{
"lststudent": [{
"rollno": 12,
"name": "sam"
}, {
"rollno": 15,
"name": "peter"
}],
"status": true,
"message": "success"
}
finally i found solution as below.
I have completed it as per solution in below URL.
http://sroze.github.io/ngInfiniteScroll/demo_async.html
Javascript Code
var mainApp = angular.module("mainApp", ['infinite-scroll']);
myApp.controller('studentcontroller', function ($scope, Reddit, $http) {
$scope.reddit = new Reddit();
myApp.factory('Reddit', function ($http) {
var Reddit = function () {
this.items = [];
this.busy = false;
this.pageno = 1;
};
Reddit.prototype.nextPage = function () {
if (this.busy) return;
this.busy = true;
var data = $.param({
rollno: $("#hdnrollno").data('value'),
pageno: this.pageno,
pagesize: 10
});
NProgress.start();
$http({
method: 'POST',
data: data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
url: 'http://www.apiservice.com/api/StudentList/GetStudent'
})
.success(function (data) {
scope = data;
var items = data.lststudent;
if (items.length <= 0)
{
NProgress.done();
return;
}
for (var i = 0; i < items.length; i++) {
this.items.push(items[i]);
}
this.pageno = this.pageno + 1;
this.busy = false;
NProgress.done();
}.bind(this));
};
return Reddit;
});
HTML Code
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngInfiniteScroll/1.2.1/ng-infinite-scroll.min.js"></script>
<div ng-app='myApp' ng-controller='StudController'>
<div infinite-scroll='reddit.nextPage()' infinite-scroll-disabled='reddit.busy' infinite-scroll-distance='1'>
<div ng-repeat="stud in reddit.items">
<span> Rollno </span> {{stud.rollno}}
<span> Student Name</span> {{stud.name}}
</div>
</div>
</div>