In an $http call, What all things we can pass in the url part, I have a server address, a user name and Password. Can i pass all as a json object?, or we have any other parameter (like url) for this.?
Can someone help me in understanding what is happening on a success call.
Specifically, the code I'm struggling with is:
app.factory('myFactory',function(){
var fact = {};
fact.getData = function(a){
$http({method:'POST',url:'http://100.100.100.100:8080/xx/xx.xx'});
$http.success(function(reply){a(reply)}
);
};
return fact;
});
See the following code, still I am not getting data from server, at the same time no errors too.
xapp.factory('loginData',function($http,$log){
var fact = {};
fact.getData = function(cred,cb){
return
$http({
method:'post',
url:'xxx.xxx.xxx.xxx:xxxx/xxxxxx',
data:cred})
.success(function(data,status,header,config){
cb(data);
})
.error(function(data,status,header,config){
$log.warn(status);
});
};
return fact;
});
xapp.controller('mainController',function($scope,$log,$http,loginData){
$scope.user = {uesr:'user',password:'123'};
loginData.getData($scope.user,function(data){
$scope.reply = data;
});
});
In the console log, I get an 'undefined'. If the http url is correct, do u see any issue?
As far as I understand, a parameter is a callback function that is executed when reply from server is received. This kills the purpose of promises that the $q service provides. Also, $http service itself does not have .success callback. It returns a promise object with .success and .error callbacks. Here's how it should be done:
app.factory('myFactory', function() {
var fact = {};
fact.getData = function() {
return $http.get('your/path/to/resource/');
}
return fact;
})
.controller('myCtrl', function($scope, myFactory) {
myFactory.getData().then(function(response){
//response.data holds your data from server
}, function(){
//this fn gets called when error happens
});
});
Some explanations: myFactory.getData() creates a new http request to the server and returns a promise object which has a method .then(successCallback, errorCallback). You can provide callbacks to the promise to be executed after request is complete.
You might get confused with my mentioned .then(successCallback, errorCallback) and .success(callback) used in your example. A generic promise that $q provides has .then method, but $http service, upon returning a promise, provides shortcuts .success() and .error() but it's the same thing in the end.
This will solve your problem of sending body.
app.factory('myFactory', function($http) {
return{
getData : function(body) {
return $http({
url: 'http://100.100.100.100:8080/xx/xx.xx',
method: 'POST',
data:body
})
}
}
});
app.controller('myCtrl', function($scope, $location, $http, myFactory){
var body ={username:uname, password:pass};
myFactory.getData(body).success(function(data){
$scope.data=data;
});
});
Related
I have this problem that is taking up too much of my development time. I have researched this problem a lot and it has now gotten me to here.
I'm making a GET request from a service. The GET request is being called from a controller.
Here is the service that makes the GET request, ajaxSrvc.js:
app.service('ajaxSrvc', ['$log', 'Constants', '$http', '$q',
function($log, Constants, $http, $q) {
this.getAllTasks = function() {
var defer = $q.defer();
var url = 'http://localhost:9998/tasks';
$http.get(url, {cache: 'true'})
.success(function(data) {
defer.resolve(data);
});
return defer.promise;
};
}
]);
That request is invoked from this controller, tasksCtrl.js:
app.controller('tasksCtrl', ["$log", "$scope", "Constants","$location", "ajaxSrvc",
function($log, $scope, Constants, $location, ajaxSrvc) {
var someData = null;
ajaxSrvc.getAllTasks().then(function(data) {
console.log(data);
someData = data;
});
console.log(someData); // This is printing NULL
}
]);
The problem arises when I try to print out someData, it prints as NULL instead of containing information from the GET request.
How do I get around this?
The problem is that you need to wait to the async function to finish. When you do console.log(someData) The code is still loading the data inside the async function. You can add a function call inside the .then function, that will execute after the load finish.
If console.log(data) is returning the expected value you should do something like this:
app.controller('tasksCtrl', ["$log", "$scope", "Constants","$location", "ajaxSrvc",
function($log, $scope, Constants, $location, ajaxSrvc) {
var someData = null;
ajaxSrvc.getAllTasks().then(function(data) {
console.log(data);
someData = data;
callWhenFinish();
});
function callWhenFinish(){
console.log(someData);
}
}
]);
This doesn't work because this is a asynchronous action, so basically the console.log(someData) is getting called before you actually get the data. It will never work.
Since getAllTasks() is a promise , someData will log first before the promise is ready.. So instead of assigning your callback data to someData within the callback scope , just pass data to a function instead then do whatever from there..
Example :
ajaxSrvc.getAllTasks().then(function(data) {
doSomethingWithData(data);
});
//Then
$scope.doSomethingWithData = function(data){
$scope.someData = data;
console.log($scope.someData);
}
Hope this helps.
I have a couple of questions on asynchronous functions in angular. I want my service function to be able to return data I get by using $http and use that data in another function. Let me demonstrate with the current code:
dashboard.servicesModule.service('SubscriptionService', function ($http, $q) {
this.getImportantData= function (param1, param2) {
var url = "my/url/with/parameters?param1=param1¶m2=param2";
$http.get(url).then(function(response){
console.log("response");
console.log(response.data); // < --- this actually shows the data i need!!
return response.data.vsyData; <--- however, this returns undefined
}, function(error){
// some error thingy just in case
});
};
this.getSomeFunctionality = function(param1, param2, param3){
var importantdata= this.getImportantData(param1, param2);
// do some filtering on the data with the purpose of returning only what i need
console.log(importantdata); <--- undefined
};
this.getEvenMoreFunctionality = function(param1, param2, param3){
var importantdata= this.getImportantData(param1, param2);
// reusing getImportantData again!
console.log(importantdata); <--- undefined
};
});
So I have been trying all kinds of things ( like this and this ) and some inventions of my own. But it starts to seem like there is no way of using the data from the $http.get anywhere else then in its own callback. And since i need the endresult in my controller, it seems like there is no other way then perform the $http.get(url).success(...some logic here) in my controller and do the filtering and other manipulation there.
However, I read here and I quote:
Our controller should be almost completely agnostic as to how data is
retrieved and sent, and should only be concerned with the general
action of sending and retrieving data to and from the service.
I interpret this as following: my controller should ask the service for the data I need and the service should make sure that it gives the data in the correct form.
The most important question is: how can I make the above code do what it needs to do or would that be impossible?
And am I supposed to do my business logic in my controller? Because here, in the angular docs I basically read that you should do business logic in your controller, but not filtering...
Its probably obvious, but ... I am an angular newbie :-).
Thanks!
Try this:
this.getImportantData= function (param1, param2) {
var url = "my/url/with/parameters?param1=param1¶m2=param2";
return $http.get(url);
};
this.getSomeFunctionality = function(param1, param2, param3){
this.getImportantData(param1, param2)
.then(function(response){
console.log(response.data.vsyData);
}, function(error){
// some error thingy just in case
});
};
this.getEvenMoreFunctionality = function(param1, param2, param3){
this.getImportantData(param1, param2)
.then(function(response){
console.log(response.data.vsyData);
}, function(error){
// some error thingy just in case
});
};
You can't get data from a method which has an asynchronous call. You can return promise, and then you can get data from promise.
For an assyncronous request you cannot make imediate return statement, tha main javascript thread will not wait for request resolution. I really recomend use $q API, is the angular implementation of Kris Kowal's Q promises/deferred systems.
function getSomething(){
var deferred = $q.defer();
$http.get('foo/bar')
.success(function(data){
$deferred.resolve(data);
});
return deferred.promise();
}
getSomething().then(function(data){
console.log(data);
});
Or you can return directly the $http promise. In case you want to remove the .then() from your controller, you can use $routeProvider with the resolve option that supports $q promises and create routes that self resolve your data, so you just inject them in controller, free of the $q proceedings.
UPDATE 1 - Practical example of resolving dependencies in routes
$routeProvider.when('/items/list', {
templateUrl: '/templates/item/list',
controller: 'ListItemsCtrl',
resolve: {
items: function(ItemsService) {
return ItemsService.getItems(); // getItems returns a promise like 'return $http.get('/items');'
}
}
});
//controller
function ListItemsCtrl($scope, items){
//do something with your items
}
function getSomething(){
var deferred = $q.defer();
$http.get('foo/bar')
.success(function(data){
$deferred.resolve(data);
});
return deferred.promise();
}
getSomething().then(function(data){
console.log(data);
});
I have a simple Angular service that uses $http to make a call to an API.
app.service("MyService", function($http){
this.api = function(obj){
return $http.post("/some-route", obj).success(function(data){
//process data in various ways here
var returnObj = {
complete: true,
data: data
};
return returnObj;
});
}
});
In the $http callback, I process the data before returning it. When I call this service in my controller, I want to get that processed data.
The following only gives me the unprocessed data:
MyService.api(someObj).success(function(data){
console.log(data);
});
How do I get the processed data from the callback?
The success function does not create a new promise, so your controller success callback is registered to the same promise as the service (the original one).
Instead you can use then, so it will create a new promise which will be resolved with your returnObj object:
// service
return $http.post("/some-route", obj).then(function(data){
// controller
myService.api().then(function(data) {
I have tested up your code in a plunker, and guess what? Its working for me. Can you please confirm it, or send me more info, i'm glad if i could help.
Plunker
var app = angular.module('plunker', []);
app.service("MyService", function($http){
this.api = function(obj){
return $http.post("http://jsonplaceholder.typicode.com/posts", obj).success(function(data){
//process data in various ways here
console.log(data);
var returnObj = {
complete: true,
data: data
};
return returnObj;
});
}
});
app.controller('MainCtrl', function($scope,MyService) {
$scope.data = 'World';
MyService.api({oi: true}).success(function(data){
$scope.data = data
});
});
Update:
I have misunderstood your question. You want to process the data in the callback to manipulate it in your action. Your code dont work because success() actually returns a promise, but it dont change it, it returns the original one. The one to go for is the then(), which is chainable and returns the modified version of the promise.
I've made changes to the plunker to reflect my new vision of the scenario. Here is the new code.
Thanks for your time.
var app = angular.module('plunker', []);
app.service("MyService", function($http){
this.api = function(obj){
return $http.post("http://jsonplaceholder.typicode.com/posts", obj).then(function(data){
//process data in various ways here
console.log(data);
var returnObj = {
complete: true,
data: data
};
return returnObj;
});
}
});
app.controller('MainCtrl', function($scope,MyService) {
$scope.data = 'World';
MyService.api({oi: true}).then(function(data){
$scope.data = data
});
});
New Plunker
Please forgive me if this is a simply problem for an angular guru, i am fairly new to services.
Below is a snippet of my controller where i have attempted make a service request to call out data from my JSON file "jobs.json".
I am not receiving an data when i load my web page neither i am seeing the JSON file in inspector element.
I assume there's something incorrect in my below code. Does anyone what the issue is?
Click here if you need to play about with the code
"use strict";
var app = angular.module("tickrApp", []);
app.service("tickrService", function ($http, $q){
var deferred = $q.defer();
$http.get('app/data/items.json').then(function (data){
deferred.resolve(data);
});
this.getItems = function () {
return deferred.promise;
}
})
.controller('tickCtrl', function($scope, tickrService) {
var promise = tickrService.getItems();
promise.then(function (data){
$scope.items= getData;
console.log($scope.items);
});
In your Plunkr, you had a few errors, such as the <script> tags around the wrong way (you need to have Angular first, so your code can then use angular.module). You also had the wrong attribute of ng-app-data instead of data-ng-app.
The key problem was with the JS code, the first parameter to the success handler for the $http.get() call is an object with a data property, which is the actual data returned. So you should resolve your promise with that property instead.
Then in the controller, like Michael P. said, getData is undefined, you should use the data parameter passed in.
app.service("tickrService", function($http, $q) {
var deferred = $q.defer();
$http.get('jobs.json').then(function(response) {
deferred.resolve(response.data);
});
this.getjobs = function() {
return deferred.promise;
}
})
.controller('tickCtrl', function($scope, tickrService) {
var promise = tickrService.getjobs();
promise.then(function(data) {
$scope.jobs = data;
console.log($scope.jobs);
});
});
See forked Plunkr.
In the success handler of your getItems function, you are storing getData, which is undefined. You want to store data instead.
Therefore, in the controller, your call to getItems() should be as follows
tickrService.getItems().then(function (data) {
$scope.items = data;
});
Also, you want to make the $http call in getItems. Like that :
this.getItems = function () {
var deferred = $q.defer();
$http.get('app/data/items.json').then(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
However, you can avoid the above boilerplate code around the promises, because $http.get returns itself a promise. Your service and controller could be much more concise and less polluted by boilerplate code.
The service could be as simple as :
app.service("tickrService", function ($http) {
this.getItems = function () {
return $http.get('app/data/items.json');
}
});
And the controller could be shortened to:
app.controller('tickCtrl', function ($scope, tickrService) {
tickrService.getItems().then(function (response) {
$scope.items = response.data;
})
});
Please note that the response resolved by $http is an object that contains (link to doc) :
data – The response body transformed with the transform functions.
status – HTTP status code of the response.
headers – {function([headerName])} – Header getter function.
config – The configuration object that was used to generate the request.
statusText – HTTP status text of the response.
Therefore in the success handler of getItems we are storing response.data, which is the response body, and not the whole response object.
In my controller I am calling a service with the following code:
Service.updateData(data).then(function (result) {
console.log(result);
});
In my service I am using $q to get multiple HTTP requests.
$rootScope.http_1 = $http.get();
$rootScope.http_2 = $http.get();
$q.all([$rootScope.http_1, $rootScope.http_2]).then(function(result) {
console.log(result[0], result[1]);
return result[0], result[1];
});
The code actually works as the http requests are successfully made. However, I get an error in the controller which says: TypeError: Cannot read property 'then' of undefined. I believe this is due the service not returning the promise in the correct way. Any ideas on how to resolve this would be much appreciated?
It looks like you are not returning the promise in updateData Try this:
updateData = function(data) {
$rootScope.http_1 = $http.get();
$rootScope.http_2 = $http.get();
return $q.all([$rootScope.http_1, $rootScope.http_2]);
}
You didn't return the promise, so there is nothing to call .then() on in your controller
You are returning inside the .then() function inside your service.updateData(), which doesn't do very much for you.
If you want to control it all inside the service and return a specific format, try this:
updateData = function(data) {
$rootScope.http_1 = $http.get();
$rootScope.http_2 = $http.get();
var defer = $q.defer();
$q.all([$rootScope.http_1, $rootScope.http_2]).then(function(result){
// process here to get the data how you want it, say in some new var foo
var foo = "some processed data based on result";
defer.resolve(foo);
});
return defer.promise;
}