I want to make a GET request using AngularJS and the GET contains email. This is the request:
var userResource = $resource('/GetUsers/?username=:username',{username:'#username'});
userResource.get({'username': 'test1#foot.com'}, function(user) {
console.log(user);
});
However, the callback function is never called. Please let me know what am I missing?
Looks good to me. Only thing i can imagine is that the callback function is not allowed to have a parameter. Angularjs Example:
var User = $resource('/user/:userId', {userId:'#id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
Related
I have question regarding AngularJS. I want to make ng-repeat for some array. But data for this array i get from firebase in controller.
Problem is, when page is rendering, iam still waiting for data from async function which get data from firebase.
What is the best way to control it?
I tried to used promisses, but something was wrong and page was rendered before i got data from firebase.
i.e
$scope.games = [];
function getOnce(){
var defer = $q.defer();
ref.once("value", function(data) {
defer.resolve();
$scope.games.push('test');
});
return defer.promise;
}
$scope.getdata = getOnce().then(function(data){
console.log('success');
console.log(data);
});
And i call '$scope.getdata' function on init 'data-ng-init="getdata()"'
What i wrong here? Or how can i get my goal?
Pass data in method resolve. In then populate the array with data response.
$scope.games = [];
function getOnce(){
var defer = $q.defer();
ref.once("value", function(data) {
defer.resolve('test');
});
return defer.promise;
}
$scope.getdata = getOnce().then(function(data){
$scope.games.push(data);
console.log('success');
console.log(data);
});
Well you could use an ng-show to just hide the parts of the page you don't want visible while you're loading the data. Or ng-if if your directives require that the data be loaded when their link/controller functions are ran by angular.
Does that suit your needs?
You'd need to expose whether or not you're done loading to the $scope with something like this:
$scope.isDoneLoading = false;
$scope.getdata = getOnce().then(function(data){
// ...
$scope.isDoneLoading = true;
});
Then you would just do this:
ng-if="isDoneLoading"
Or this, depending on your needs:
ng-show="isDoneLoading"
I am just trying FB JS api and want to know whether or how I can still use "response" out of FB.api. For example:
var picture;
FB.api('/me/picture?width=180&height=180', function (response) {
picture = response.data.url;
console.log(picture);
});
alert(picture);
The above code will show "undefined" in alert window.
Is there a way to use "response.data.url" out of FB.api?
Thanks
Update:
Here is the big picture: I need retrieve some information from FB user account, such as /me/name, /me/address/city, /me/picture.data.url and group them together and then send the information to server through AJAX.
var name;
var city;
var picture;
FB.api('/me', function (response) {
name = response.name;
FB.api('/me/address', function (adrresponse) {
city = adrresponse.city;
}
FB.api('/me/picture', function (imgresponse) {
picture = imgresponse.data.url;
}
//since FB API is async, the following is not correct!!!
var params = "name="+name+"&city="+city+"&picture="+picture;
//send out through AJAX.
var http = new XMLHttpRequest();
http.open("POST", url, true);
}
Is there a better way to finish the above job?
Update 2:
The best way is to use fields expansion
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#fieldexpansion, as shown by the answer of this question.
Thanks
Derek
The problem is the picture variable is not populated at the time that the alert fires. It will only be populated after the FB.api callback completes.
var picture;
FB.api('/me/picture?width=180&height=180', function (response) {
picture = response.data.url;
// this would work correctly
alert(picture);
});
What are you attempting to do with the picture variable? Perhaps you should call a function do something with the picture inside your callback:
var picture;
FB.api('/me/picture?width=180&height=180', function (response) {
picture = response.data.url;
doSomethingWithPicture(picture);
});
Update
The simple way to achieve what you are after is this:
FB.api('/me', function (response) {
var name = response.name;
FB.api('/me/address', function (adrresponse) {
var city = adrresponse.city;
FB.api('/me/picture', function (imgresponse) {
var picture = imgresponse.data.url;
doAjax(name, city, picture);
}
}
}
function doAjax(name, city, picture) {
//since FB API is async, the following is not correct!!!
var params = "name="+name+"&city="+city+"&picture="+picture;
//send out through AJAX.
var http = new XMLHttpRequest();
http.open("POST", url, true);
}
However, this is not ideal as you have to wait for /me/address before you can call /me/picture.
Here are some other options
you need to call /me first.
you fire off both api calls and execute code when the both complete
Ways to accomplish #2
You could then use a promise library to chain the /me/address and /me/picture/. See: https://github.com/kriskowal/q or https://api.jquery.com/category/deferred-object/ to get started
Call a callback after each that conditionally fires the ajax if both address and picture are set
I am sure there are a number of other ways:
How to chain ajax requests?
How to chain ajax calls using jquery
Update #2
This is the best way to accomplish what you are after (no additional callbacks required)
FB.api('/me', {fields: ['first_name', 'last_name', 'picture', 'address']}, function(response) {
// response will now have everything you need
console.log(response);
});
I did not give this answer originally as it was not the topic of the question which seemed to be scoping.
I have built a simple application in Angular consuming a simple API I created myself using Laravel. The application is hosted here. The API is hosted here. Now I can log in to the application at which point the API returns a simple auth_token which is sent as the URL parameter in every subsequent request that is sent to the server.
There is only one user in the system:
Email: admin#admin.com
Password: admin12345
You can log into the application using these credentials at which point the application will set a cookie using the $cookieStore service and will use the token in this cookie for every subsequent request. After using the application, a user can log out from the application, where a DELETE request is sent to the server and on the success method, the cookie is deleted from the browser.
Unfortunately there is some issue with the code I suppose. The DELETE request is working as expected and it deletes the auth_token on the server and returns 200 OK. But the success method is not called. I am not sure what I am doing wrong. It might be just a syntax problem.
app.js
function AppCtrl ($scope, $cookieStore, $location, Auth) {
$scope.setActive = function (type) {
$scope.destinationsActive = '';
$scope.flightsActive = '';
$scope.reservationsActive = '';
$scope[type + 'Active'] = 'active';
};
$scope.authenticate = function (credentials) {
Auth.save(credentials, function(data){
$cookieStore.put('auth_token', data.auth_token);
$scope.isLoggedIn = true;
$location.path('destinations');
$scope.message = null;
}, function(data){
$scope.message = "Email/Password combination incorrect!";
});
};
$scope.logout = function () {
//var auth_token = $cookieStore.get('auth_token');
Auth.delete({
'auth_token': $cookieStore.get('auth_token')
}, function(data){
$scope.isLoggedIn = false;
$cookieStore.remove('auth_token');
});
};
if($cookieStore.get('auth_token')){
$scope.isLoggedIn = true;
}else{
$scope.isLoggedIn = false;
}
}
The logout function is called when the log out button is pressed. What am I doing wrong here?
Note: The application is not working on Chrome for some reason (Use Firefox). If you can shed some light on that, it would be very helpful.
Both the repositories are public if you wish to have a look:
AngulAir Application: http://gitlab.learningtechasia.com:8901/rohan0793/angulair.git
AngulAirAPI: http://gitlab.learningtechasia.com:8901/rohan0793/angulairapi.git
Here is your solution
$scope.logout = function () {
//var auth_token = $cookieStore.get('auth_token');
Auth.delete(
{'auth_token': $cookieStore.get('auth_token')}, // parameters
{},//postData, which you don't need for this
function(data){
$scope.isLoggedIn = false;
$cookieStore.remove('auth_token');
},
// error callback
function (httpResponse) {
// do what you want for error handling here
}
);
};
Note:-> (Below points solved the problem)
Only the 2nd option(postdata) in $resource.delete API was missing. We should give it as a blank {} if it is not required for API.
And delete method should return 204 Status Code in order to execute success callback.
I am using facebook login api to get user information, code can exceed correctly and FirstName can get from facebook api, but the first alert has correct value, the second value is still "". First I think it is because remote call time cause the second alert is before the first alert, after I using a delay function before second alert, also I can not get value in the second alert.
Part of code like below.
if (response.status === 'connected') {
FirstName="";
LastName="";
FB.api('/me', function(response) {
FirstName = response.first_name;
LastName = response.last_name;
Email = response.email;
alert(FirstName);
});
alert(FirstName);
}
FB.Api is asynchronies method, which will post/get to a remote server.
The execution don’t wait for it to finish before your second “alert”
The only way you can be sure your FirstName is initialized, is using callbacks or MVVM pattern.
Here MVVM with knockout.js code:
var fbModel = function () {
var self = this;
self.FirstName = ko.observable("");
self.FirstName.subscribe(function () {
//DO what you want, first name just been changed from FB
});
self.load = function () {
FB.api('/me', function (response) {
self.FirstName(response.first_name); // WILL TRIGGER self.FirstName.subscribe
});
};
};
And don’t forget, applying this model is easy, I can give you some links if you want. (But just go and look on examples on their site)
Edit : callback version
var FirstName = ""; // Global
function callback(name) {
//your name has been loaded
FirstName = name; // Global is initialized
};
function load (callback) {
FB.api('/me', function (response) {
callback(response.first_name);
});
};
//Now just call the load :
load(callback);
var Model = function() {
function checkStatus(){
JsonClient.onload = function() {
};
JsonClient.onerror = function(e) {
};
}
}
I know the error handler would be called when my request parameter is wrong or may be even if the service is down too.
But is there any way i can check my service is down at first place before sending the data.