Facebook API fetching user's first name - facebook-javascript-sdk

I'm trying to write a simple function which returns the current FB user first name.
I've been getting some odd responses so I added some bits to track down where the issue is.
function firstName(){
var userName="Default Name";
FB.api('/me', function(response) {
if (!response || response.error) {
alert('Error occured fetching first name');
userName="Name Error";
} else {
userName=response.first_name;
console.log("TestPoint1: " + userName);
}
});
console.log("Test Point2: " + userName);
return userName;
}
But if I call it using console.log("testCall: " + firstName); I get the following response in this order:-
Test Point2: Default Name
TestCall: Default Name
TestPoint1: Pete
So the function appears returning before the FB api call has finished.
Any ideas?

Welcome to the world of asynchronous programming :)
The callback of the API call will get called asynchronously, so Test Point 2 will get called immediately after FB.api, but the function with the response will get called later.
Correct solution (you can´t work with "return"):
function firstName(callback){
FB.api('/me', function(response) {
if (!response || response.error) {
callback('Name Error');
} else {
callback(response.first_name);
}
});
}
firstName(function (response) {
console.log(response);
});
You can also use "Promises", but it´s not necessary in that case.

Related

Nuxtjs - Authentication

I wrote a sign up functionality in nuxtjs. It saves a new user in my database. However, there seems to be a problem with generating a token afterwards, to log in the user.
The register action gets called by a method in the register component. It returns the error response in the catch block. It seems to fail after the token is generated on the server.
Action in the store
async register ({ commit }, { name, slug, email, password }) {
try {
const { data } = await this.$axios.post('/users', { name, slug, email, password })
commit('SET_USER', data)
} catch (err) {
commit('base/SET_ERROR', err.response, { root: true })
throw err
}
}
Post function on the nodejs server
router.post('/users', async (req, res) => {
try {
const body = _.pick(req.body, ['name', 'slug', 'email', 'password']);
const user = new User(body);
await user.save();
const token = await user.generateAuthToken(); // execution seems to fail on this line
console.log(token); // never gets called
req.session['token'] = 'Bearer ' + token;
req.session['user'] = user;
res.header('Authorization', 'Bearer ' + token).send(user);
} catch (err) {
res.status(400).json({ message: "Der Account konnte leider nicht erstellt werden" });
}
});
GenerateAuthToken function in mongo model User
UserSchema.methods.generateAuthToken = function () {
var user = this;
var access = 'auth';
var token = jwt.sign({_id: user._id.toHexString(), access}, process.env.JWT_SECRET).toString();
user.tokens.push({access, token});
return user.save().then(() => {
return token;
});
};
Error message
I would be tremendously thankful for any kind of help!
Maybe it doesn't help too much, but I would try to create a dummy token and try to make everything works with it. One of my debugging techniques is to isolate every single part of my code and be sure that everything works piece for piece, maybe that technique is slow but most of the time it works.
If everything works, I would continue debugging the generateAuthToken function.
If your console log never gets called, then the error could be in the function.
I hope it helps a little and sorry I don't know too much about MongoDB but everything seems to be ok.

Catch React Native fetch error without halting the app with red screen

I am making a React Native function that pulls the HTML of a webpage. It works fine if the URL exists and I receive a 200 status code. However, when I put a wrong url in there (something that would receive a 404 error), it displays a red screen that says "Network request failed." I'd like to catch the error without the whole app halting and display an alert to the user. How can I go about doing that?
fetchEvents() {
fetch('http://www.wrongurl.com', {
method: 'GET',
redirect: 'follow'
})
.then(function(response) {
if (response.status == 200) {
let responseText = JSON.stringify(response.text());
console.log(responseText);
}
else throw new Error('HTTP response status not code 200 as expected.');
})
.catch(function(error) {
console.error(error);
return error;
});
}
This is how I solved this, making graceful errors that don't crash the app using promises:
In my API service class:
fetchEvents() {
let thisCurrentAPIService = this;
return new Promise(
function (resolve, reject) {
fetch('http://www.wrongurl.com');
.then(
function(response) {
if (response.ok) {
let responseText = JSON.stringify(response.text());
console.log(responseText);
}
else {
reject(new Error(`Unable to retrieve events.\nInvalid response received - (${response.status}).`));
}
}
)
.catch(
function(error) {
reject(new Error(`Unable to retrieve events.\n${error.message}`));
}
);
}
);
}
Then I call it from my React Component. If I receive an error, I create the alert there.
this.state.apiService.fetchEvents()
.then(
function (value) {
console.log('Contents: ' + value);
},
function (reason) {
Alert.alert(`${reason.message}`);
});
Hilarious, three years almost and no proper answer still.
However, console.error(error) is what actually causing the app to throw a red screen.
You can use Alert component from react-native.
fetchEvents() {
fetch('http://www.wrongurl.com', {
method: 'GET',
redirect: 'follow'
})
.then(function(response) {
if (response.status == 200) {
let responseText = JSON.stringify(response.text());
console.log(responseText);
}
else throw new Error('HTTP response status not code 200 as expected.');
})
.catch(function(error) {
Alert.alert(error); // Using this line
});
}
But I prefer using toast like on Android than alert.
console.warn('This is my error');
If this is simply for dev it might help. It explicitly uses the little warning toast to provide whatever feedback you need. Note: this is definitely not for production use.
Add following in app index.js file
console.reportErrorsAsExceptions = false;

Express REST API - Delete Method

I am getting stuck on the delete method for my API. My application requires a user to log in and then he can add courses. The courses are stored in a nested array inside the User model. I want the user to be able to cancel (delete) a course from the view and then have the course deleted from the user's profile on the server. I am getting a 404 response event though the variables I am comparing are identical.
This is my ajax call to delete a specific course:
jQuery.ajax({
url: "/test/signups/5387c1a0fb06e48f4658170c",
type: "DELETE",
success: function (data, textStatus, jqXHR) {
console.log("Post resposne:");
console.dir(data);
console.log(textStatus);
console.dir(jqXHR);
}
});
This is my delete method:
app.delete('/test/signups/:id', isLoggedIn, function(req, res) {
User.findOne({'_id': req.user.id }, function(err, user) {
if (err)
return done(err);
if (user) {
var found = false;
var singlesignup = user.signup.filter(function(e){ return e._id == req.params.id })[0]
user.signup.forEach(function (singlesignup, index) {
if (singlesignup._id === req.params.id) {
found = index;
}
});
if(found) {
user.signup.splice(found, 1);
res.json(200, {status: 'deleted'});
} else {
res.json(404, {status: 'invalid survey question deletion'});
}
}
});
});
The _id values in mongodb are not strings, they are instances of the ObjectId class and they don't work correctly with the == or === operators. It's completely a nuisance. But anyway try converting them to strings before comparing: singlesignup._id.toString() === req.params.id. To get it truly correct in the long run, make sure you handle all the cases of null, string or ObjectId. Consider a helper library such as objectid.

firebase simple authentication authClient is null?

Below is the sample code I am playing around with:
var myRootRef = new Firebase('https://url.firebaseIO.com/');
var authClient = new FirebaseAuthClient(myRootRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
} else {
// user is logged out
console.log('logged out!');
login();
}
});
function login(){
var email = "something#gmail.com";
var password = "123";
authClient.login('password', {
email: email,
password: password,
rememberMe: true
});
}
The error I get back is : Cannot call method 'login' of undefined
authClient seems to be always null? What am I doing wrong?
Here authClient seems good. I think problem with scope of the login() function.Try this
var myRootRef = new Firebase('https://url.firebaseIO.com/');
var authClient = new FirebaseAuthClient(myRootRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
} else {
// user is logged out
console.log('logged out!');
var email = "something#gmail.com";
var password = "123";
this.login('password', {
email: email,
password: password,
rememberMe: true
});
}
});
When you initially call new FirebaseAuthClient, it's going to invoke the callback with the current login state (The user could already be logged in, for instance, when this is invoked). This callback occurs before new FirebaseAuthClient returns, which means that authClient has not been assigned yet.
You do not need to move the your authClient.login inside the callback, although this works fine. You just need to be aware of the fact that the first time this callback is issued might be before the assignment.
You could, for instance, use a setTimeout around your call to ensure the variable is set first:
var authClient = new FirebaseAuthClient(myRootRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
} else {
// user is logged out
console.log('not logged in yet or logged out again!');
setTimeout(login, 1);
}
});

send post request using node-trello module

I am new to trello api and i am using node.js with it. GET request is working fine with node.js but when i am sending POST request to store list in the particular board then it gives me a unauthorize error. my code is :
t.post('/1/boards/board_id/lists?scope=read,write',{text:'test'}, function(err,data){
if(err){
console.log("err "+err);
return res.send(err);
}
else{
console.log(data);
return res.send(data);
}
});
please anyone tell me where i am doing wrong.
I see a couple of things that could be going wrong.
First, did you request an api token with scope=read,write? If you're following the instructions at https://github.com/lmatteis/node-trello, you need to do
https://trello.com/1/connect?key=YOUR_PUBLIC_KEY&name=MyApp&response_type=token&scope=read,write
to get a token capable of read and write (replacing YOUR_PUBLIC_KEY with your actual public key).
Second, just to make sure, you are substituting the board id in question for board_id in the post URL, right?
Finally, 'text' should probably be 'name'.
So to put it all together, here is something that should work:
var Trello = require("node-trello");
var t = new Trello("[YOUR API KEY]", "[YOUR TOKEN THAT YOU GOT BY HITTING trello.com?connect URL ABOVE]");
t.get("/1/boards/[THE ID OF THE BOARD]/lists", function(err, data) {
if(err) throw err;
console.log(data);
});
t.post('/1/boards/[THE ID OF THE BOARD]/lists', {name:'test'}, function(err,data){
if (err) {
console.log("err " + err);
} else {
console.log(data);
}
}
);
If you would like to check the attributes of a token you have issued, you can do that via the API, too (see https://trello.com/docs/api/token/index.html).