Why in this code -> JSON get with angular and PHP , the service return an empty array but if i write:
angular.module('pageModule')
.factory('pageService', function($http){
var pagesArray = new Array();
return{
pagesArray: pagesArray,
load: function(){
$http.get('../angCMS/server/php/page.php')
.success(function(res){
pagesArray.push(res);
});
}
};
});
Controller:
angular.module('pageModule')
.controller('pageController', ['$scope', 'homeService', 'pageService', function($scope, homeService, pageService){
$scope.pages = pageService.pagesArray;
pageService.load();
}]);
everything works great?
Why are you not waiting for the call to be made. Make use of the promise that the $http is returning.
Factory:
// Original
angular.module('pageModule')
.factory('pageService', function($http){
var pagesArray = new Array();
return{
pagesArray: pagesArray,
load: function(){
$http.get('../angCMS/server/php/page.php')
// Success is deprecated use then and catch
.success(function(res){
pagesArray.push(res);
});
}
};
});
// Changed
angular.module('pageModule')
.factory('pageService', function($http){
var pagesArray = new Array();
return{
pagesArray: pagesArray,
load: function(){
return $http.get('../angCMS/server/php/page.php')
.then(function(res){
pagesArray.push(res);
return pagesArray;
});
}
};
});
Controller:
//Original
angular.module('pageModule')
.controller('pageController', ['$scope', 'homeService', 'pageService', function($scope, homeService, pageService){
$scope.pages = pageService.pagesArray;
pageService.load();
}]);
//Changed
angular.module('pageModule')
.controller('pageController', ['$scope', 'homeService', 'pageService', function($scope, homeService, pageService){
$scope.pages = [] //Initiale state;
//Make use of the HTTP promise that is returned in the load
pageService.load()
.then(function (pages) {
$scope.pages = pages;
})
.catch(function (error) {
//Handle error
console.log(error);
});
}]);
Related
I want to wait for an http response before exiting angular controller. I have written the following code. But id doesn't work as the controller still exits before the http call is returned. Can anyone help me out to fix this? Thanks in advance.
var app = angular.module('app', []);
app.factory('MyService', function ($http) {
return $http.get('/api/endpoint').then(function(res){
return res.data;
});
});
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.then(function(data){
$scope.myVarialbe = data;
})
}]);
I would write this as below.
'use strict';
(function () {
function MyService($http) {
function getService() {
var url = yourURL;
return $http({ method: 'GET', cache: false, url: url });
}
return {
getService: getService
};
}
angular.module('app')
.factory('MyService', MyService);
}());
controller code:
MyService.getService().then(function(response) {
});
You can use like this factory just return request response promise and in controller use .then on returned promise.
var app = angular.module('app', []);
app.factory('MyService', ['$http',function($http) {
return {
getData: function() {
return $http.get('/api/endpoint');
}
};
}]);
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.myVarialbe = response.data;
});
}]);
Use $q is better.
Eg:
app.factory('MyService', ['$http', '$q', function($http, $q) {
return {
getData: function() {
var deferred = $q.defer();
$http.get('/api/endpoint')
.then( function(resp) {
deferred.resolve( resp.data );
});
return deferred.promise;
}
};
}]);
app.controller('MyController', ['$scope', 'MyService',function($scope, MyService){
MyService.getData().then(function(data){
$scope.myVarialbe = data;
})
}]);
I have this in the controller
angular.module('myApp')
.controller('TaskController', function ($scope, TaskFactory) {
$scope.addTodo = function () {
$scope.todos.push({text : $scope.formTodoText});
$scope.formTodoText = '';
};
});
and this in the factory
angular.module('myApp')
.factory('TaskFactory', function ($q, $http) {
var sendTasks = function(params) {
var defer = $q.defer();
console.log(1, params);
$http.post('http://localhost:3000/task/save', params)
.success(function(data) {
console.log(2);
console.log('data', data);
})
.error(function(err) {
defer.reject(err);
});
return defer.promise;
}
return {
sendTask: function(taskData) {
console.log('taskData', taskData);
return sendTasks('/task/save', {
taskData : taskData
})
}
}
});
all I need is to know, how to send the data from the controller to the factory in order to do the POST to the specified route ?
You just need to call the function/method inside factory with the required params.
angular.module('myApp')
.controller('TaskController', function ($scope, TaskFactory) {
$scope.addTodo = function () {
$scope.todos.push({text : $scope.formTodoText});
TaskFactory.sendTask({data : $scope.formTodoText})
$scope.formTodoText = '';
};
});
You can follow Dan Wahlin blog post.
Controller:
angular.module('customersApp')
.controller('customersController', ['$scope', 'dataFactory', function ($scope, dataFactory) {
$scope.status;
dataFactory.updateCustomer(cust)
.success(function () {
$scope.status = 'Updated Customer! Refreshing customer list.';
})
.error(function (error) {
$scope.status = 'Unable to update customer: ' + error.message;
});
}
Factory:
angular.module('customersApp')
.factory('dataFactory', ['$http', function($http) {
var urlBase = '/api/customers';
dataFactory.updateCustomer = function (cust) {
return $http.put(urlBase + '/' + cust.ID, cust)
};
}
Hope that solve your problem.
You can call the function directly on the TaskFactory that you pass into the controller as a dependency.
I've cleaned up your code a bit and created a plunk for you here:
And here's the code:
Controller
(function(angular) {
// Initialise our app
angular.module('myApp', [])
.controller('TaskController', function($scope, TaskFactory) {
// Initialise our variables
$scope.todos = [];
$scope.formTodoText = '';
$scope.addTodo = function() {
// Add an object to our array with a 'text' property
$scope.todos.push({
text: $scope.formTodoText
});
// Clear the input
$scope.formTodoText = '';
// Call function to send all tasks to our endpoint
$scope.sendTodos = function(){
TaskFactory.sendTasks($scope.todos);
}
};
});
})(angular);
Factory
(function(angular) {
angular.module('myApp')
.factory('TaskFactory', function($q, $http) {
var sendTasks = function(params) {
var defer = $q.defer();
$http.post('http://localhost:3000/task/save', params)
.success(function(data) {
console.log('data: ' + data);
})
.error(function(err) {
defer.reject(err);
});
return defer.promise;
}
return {
sendTasks: sendTasks
}
});
})(angular);
I created a service that fetches data from local json and use it in a controller to display it in browser. All are working fine. here is my code:
JS Code:
var myApp = angular.module("myApp", ['ngRoute']);
myApp.service("dataService", function($http, $q){
var deferred = $q.defer();
$http.get('json/link.json').then(function(data){
deferred.resolve(data);
});
this.getData = function(){
return deferred.promise;
}
})
.controller("linkCtrl", function($scope, dataService) {
var promise = dataService.getData();
promise.then(function(data) {
$scope.links = data.data;
});
});
Now, i have another json link (for eg.: json/link2.json ) and i want to perform the same function. Is there any way to use the "dataService" service ( like changing the link ).
I don't want to re-create a new service which does the same function. Any idea to re-use the Service for different json data ?
Thanks in Advance
Just create a method you can pass url to:
myApp.service("dataService", function($http){
this.getData = function(url){
return $http.get(url); // this returns a promise
};
})
Use it like this:
.controller("linkCtrl", function($scope, dataService) {
var promise1 = dataService.getData('json/link.json');
promise1.then(function(data) {
$scope.links = data.data;
});
var promise2 = dataService.getData('json/link2.json');
promise2.then(function(data) {
$scope.links2 = data.data;
});
});
Try something like this
myApp.service("dataService", function($http){
this.getData = function(link,callback){
$http.get(link).then(function(data){
if(callback)
callback(data);
});
});
myApp.controller("linkCtrl", function($scope, dataService) {
dataService.getData('json/link.json', function(data){
$scope.links = data.data;
});
});
I am using AngularJS to set up a table and filter its data by a search or category keywords. I
AngularJS
categorieFilter = angular.module("categorieFilter", [])
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.categories = store.getCategories();
$scope.products = store.getProducts();
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
categorieFilter.factory('store', function($http){
return {
getCategories: $http.get('api/categories').success(function (data) {
return data;
}),
getProducts : $http.get('api/products').success(function (data) {
return data;
}
};
});
The $http.get on its own is working, when I surf directly to my api I get the required data. Also when I do a alert(data) ifter the $hhtp.get in categories, I get the data I need... So this should be working but it doesn't. I get an error:
TypeError: store.getCategories is not a function
And I got no clue where this is coming from. Anybody a solution to this problem?
When using a factory you should do new function to return a constructor:
function myFactoryFunction() {
return function() {
var a = 2;
this.a2 = function() {
return a*2;
};
};
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();
From this detailed post angular.service vs angular.factory
In your case
var storeFactory = new store();
storeFactory.getProducts();
Updated version, with TS code:
categorieFilter = angular.module("categorieFilter", [])
/**
Store factory
*/
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
store.getCategories().then(function(data){
$scope.categories = data;
})
store.getProducts().then(function(data){
$scope.products = data;
})
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
/**
Store factory
*/
categorieFilter.factory('store', function($http, $q){
function _getCategory (){
var deferred = $q.defer();
$http.get('api/categories').success(function (data) {
deferred.resolve(data);
})
return deferred.promise;
}
function _getProducts (){
var deferred = $q.defer();
$http.get('api/products').success(function (data) {
deferred.resolve(data);
}
return deferred.promise;
}
return {
getCategories: _getCategory,
getProducts : _getProducts
};
});
I usually create services using $resource. You could try this:
categorieFilter = angular.module("categorieFilter", []);
categorieFilter.factory('categoryStore', [
'$resource',
function($resource) {
return $resource('/api/categories/', {}, {
getCategories: { method: 'GET', params: {} },
});
}
]);
categorieFilter.factory('productsStore', [
'$resource',
function ($resource) {
return $resource('/api/products/', {}, {
getProducts: { method: 'GET', params: {} },
});
}
]);
categorieFilter.controller("catFilter", [
"$scope", "categoryStore", "productsStore", function ($scope, categoryStore, productsStore) {
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.categories = categoryStore.getCategories();
$scope.products = productsStore.getProducts();
$scope.filterProductsByCats = function(category) {
$scope.search = category;
};
}
]);
I usually write http factories passing a callback function parameter (I usually work with Node and I'm used to do this for long working functions). Taking your code it will looks something like this:
categorieFilter = angular.module("categorieFilter", [])
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
store.getCategories(function(err, data){
if(!err)
$scope.categories = data;
});
store.getProducts(function(err, data){
if(!err)
$scope.products = data;
});
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
categorieFilter.factory('store', function($http){
return {
getCategories: function(next){
$http.get('api/categories')
.success(function (data) {
next(null, data);
})
.error(function(headers, status){
next(status, null);
});
},
getProducts : function(next){
$http.get('api/products')
.success(function (data) {
next(null, data);
})
.error(function(headers, status){
next(status, null);
});
}
};
});
As you can see now factory takes a callback that will be called with error and data parameters, so error handling can be delegate or not to the controller. This is pretty useful for complex situations.
Here's a plunker that works using $q and defer explicitly with some random JSON.
var app = angular.module('categorieFilter', []);
app.factory('store', function($http, $q){
return {
getCategories: function() {
var deferred = $q.defer();
$http.get('https://api.myjson.com/bins/2gamd')
.success(deferred.resolve)
.error(deferred.resolve);
return deferred.promise;
}
}
})
.controller('catFilter', function($scope, store){
store.getCategories().then(function(data) {
$scope.categories = data.stories;// change data.stories to whatever your data is
});
});
I have create my own LoggerService but if I use it I get error:
FOrder.query is not a function
If i remove all LoggerService calls in controller all work fine, why i can't use LoggerService?
services.js
angular.module('GSAdmin.services', ['ngResource'])
.factory('FOrder', ['$resource', function($resource) {
return $resource('/api/order/:orderId');
}])
.service('LoggerService', [function(){
var _logList = [];
this.getLast = function(){
return _logList[_logList.length-1];
};
this.getLog = function(){
return _logList;
};
this.log = function(text) {
_logList.push(text);
};
}])
controller.js
.controller('OrderController', ['$scope', 'FOrder', 'LoggerService',
function($scope, FOrder, LoggerService) {
FOrder.query(function(data){
$scope.orders = data;
});
$scope.log = LoggerService.getLog();
LoggerService.log('Begin editing order #' + field.id);
}]);
.controller('OrderController', ['$scope', 'FOrder', 'LoggerService', function($scope, FOrder, LoggerService) {
FOrder.query(function(data){
$scope.orders = data;
});
$scope.log = LoggerService.getLog();
LoggerService.log('Begin editing order #' + field.id);
} <-- **you missed that bracket**
]);
Problem was in 'FOrder', 'LoggerService', i dont know why is important, but when i switch it to 'LoggerService', 'FOrder', all fine work.