This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I am getting this weird issue in facebook login where I get the response but after getting the response, I am not able to dispatch actions.
Therefore, I wrote a function to do this but I am getting this.setData is not a function.
testAPI() {
window.FB.api('/me' ,function(response) {
console.log("testAPI",response);
if(response){
userProfile = {
access_token:accessToken,
id:response.id,
name:response.name,
provider: "Facebook",
};
console.log("userProfile",userProfile);
this.setData(userProfile);
}
console.log('[FacebookLoginButton] Successful login for: ', response);
});
}
setData = userProfile => {
this.setState(
{
userData: userProfile
},
() => {
console.log("inside setData");
if (userProfile !== undefined) {
console.log("inside callback", userProfile);
this.props.loginUser(this.state.userData);
}
}
);
};
This will help ( https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56 ) [ You need to bind function in order to set context of this ]
You have to use arrow function, or bind function to set correct context of this.
window.FB.api('/me', response => {
// function body
}
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 2 years ago.
I have two classes in a function and for some reason in the second function this is not being recognised correctly.
The classes are Emitter and Receiver.
I am trying to figure out why this is not being picked up correctly here. The log is included in the code below:
const chat = (messages) => {
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.event = () => {};
}
setEvent(fn) {
this.event = fn;
}
trigger() {
this.messages.forEach(message => this.event(message));
}
}
class Receiver {
constructor() {
this.messages = [];
// this prints correctly here
---> Receiver { messages: [] }
console.log('this ===> ', this)
}
ping(message) {
console.log('this ===>', this)
// this here prints the following
this ===> Emitter {
messages: [ 'Hi', 'Hola', 'Bonjour', 'Hi' ],
event: [Function: ping] }
this.messages.push(message);
}
}
const myReceiver = new Receiver();
const myEmitter = new Emitter(messages);
myEmitter.setEvent(myReceiver.ping);
myEmitter.trigger();
return myReceiver.messages;
};
The this depends on the scope where it is called but not the scope it is defined.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
In the call myEmitter.setEvent(myReceiver.ping), only the function ping is passed to the myEmitter, not its scope myReciever. In case if you would like to pass myRevciever scope you can bind it the function call.
myEmitter.setEvent(myReceiver.ping.bind(myReceiver));
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I'm trying to wait for data in componentDidMount and then change my state isLoading to false but setState is not triggering. I'm able to console.log the data inside branch.init but I don't know why setState is not working.
state = {
isLoading: true,
}
componentDidMount() {
console.log("componentDidMount");
let branchKeyTest = 'key_test_aBcDeF'
branch.init(branchKeyTest, function(err, data) {
console.log(JSON.stringify(data, null, 1))
this.setState({ isLoading: false })
if (data && data.data_parsed) {
switch (data.data_parsed.link_type) {
case 'new_release':
localStorage.setItem('redirect', JSON.stringify({
'link_type': 'new_release',
'release_id': data.data_parsed.release_id
}));
break;
default:
console.log("do nothing")
}
}
})
}
render() {
const { isLoading } = this.state;
if (!isLoading) {
return (
<div>Done Loading</div>
)
else {
return (
<div>Still Loading</div>
)
}
}
branch.init(branchKeyTest, function(err, data) { needs to be changed to branch.init(branchKeyTest, (err, data) => { because you don't have access to the class's this keyword inside the anonymous function.
The way you wrote it, you don't have access to this because this was referring to the function's context - not the class. By changing it to fat arrow syntax, you can access this for the React class's context.
You can read more about this here.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
i have started working on a small project using VueJs, i've made a get request using Axios library which returns some data as expected, but I cannot call loadUsers function using this inside mounted
this is my code:
export default{
data(){
return {
users : {}
}
},
methods:{
addCustomer(){
//var form = document.querySelector('#add-customer');
var formData = $('#add-customer').serialize();
axios.post('/Thirdparty', formData).then(function(response){
helper.validation(response.data);
//alert(response.data.error);
});
},
loadUsers(){
axios.get('/Thirdparty/loadUsers').then(function(data){
this.users = data.data;
});
}
},
created(){
let self=this
self.loadUsers();
}
}
as you can see also i've used self variable to call my loadUsers() function, but i'm still getting
this is undefined error
You're referencing this.users within the callback to axios.get().then() in loadUsers(). Due to you're using a standard function and not an arrow function, this is not referring to the Vue instance, i.e. the scope for this is now incorrect. Either use an arrow function or change the reference:
// Do this...
export default{
data(){
return {
users : {}
}
},
methods:{
addCustomer(){
//var form = document.querySelector('#add-customer');
var formData = $('#add-customer').serialize();
axios.post('/Thirdparty', formData).then(function(response){
helper.validation(response.data);
//alert(response.data.error);
});
},
loadUsers(){
axios.get('/Thirdparty/loadUsers').then((data) => { // Using an arrow function.
this.users = data.data;
});
}
},
created(){
let self=this
self.loadUsers();
}
}
// Or this...
export default{
data(){
return {
users : {}
}
},
methods:{
addCustomer(){
//var form = document.querySelector('#add-customer');
var formData = $('#add-customer').serialize();
axios.post('/Thirdparty', formData).then(function(response){
helper.validation(response.data);
//alert(response.data.error);
});
},
loadUsers(){
let self=this; // Adding "self"
axios.get('/Thirdparty/loadUsers').then(function(data){
self.users = data.data; // Referencing "self" instead of "this".
});
}
},
created(){
let self=this
self.loadUsers();
}
}
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I have the following but I get error Cannot read property 'push' of undefined:
var vm = new Vue({
el: '#root',
data: {
posts: [],
newPost: {}
},
createPost: function() {
axios.post("api/posts/create", this.newPost).then(function (response) {
this.posts.push(response.data);
})
}
});
In my network tab in chrome dev tools I can see response.data is clearly an object:
{
"id": 131,
"postContent": "<p>test</p>\n",
}
So why I'm i getting this error?
That's because this context is assigned incorrectly which means that this does not point on the Vue component. To solve this problem, you can use => syntax which simply means a sophisticated way of this self = this outside of the target callback.
createPost: function() {
axios.post("api/posts/create", this.newPost).then((response) => {
this.posts.push(response.data);
})
}
As IzumiSy said, this very common problem when using axios or even setTimeout function. You can use es6 arrow synax, create temporary local variable with vm or bind it to the function.
ES6
createPost: function() {
axios.post("api/posts/create", this.newPost).then((response) => {
this.posts.push(response.data);
})
}
Temporary variable
createPost: function() {
let vm = this;
axios.post("api/posts/create", this.newPost).then(function (response) {
vm.posts.push(response.data);
})
}
Binding
createPost: function() {
axios.post("api/posts/create", this.newPost).then(function (response) {
this.posts.push(response.data);
}.bind(this))
}
This question already exists:
Why isn't my future value available now? [duplicate]
Closed 6 years ago.
I am trying to get my Angular2 service to use the LinkedIN javascript SDK that is loaded by the script linkedin provides. the functionality works for getting the data and returning it but I can't set the local function variable to the data I got back from linkeidn
export class LinkedInAuthService {
constructor(
) {
}
linkedInAuthorization() {
window['IN'].User.authorize();
window['IN'].Event.on(window['IN'], 'auth', this.getLinkedInUserInfo);
}
getLinkedInUserInfo() {
let linkedinInfo:any;
window['IN']
.API
.Raw()
.url("/people/~:(firstName,lastName,emailAddress,industry,specialties,positions)?format=json")
.result(function(data:any){
console.log(data) //logs data correctly
linkedinInfo = data
});
console.log(linkedinInfo) // undefined
}
AuthLinkedInUserforGlx() {
console.log(localStorage.getItem('linkedinInfo'))
}
}
I think the problem is when I set linkedinInfo = data it is not setting it locally, just not sure how to make it local
This worked for me
export class LinkedInService {
IN = window['IN'];
userProfile: Object;
constructor() {
this.userProfile = JSON.parse(localStorage.getItem('profile'))
this.IN.Event.on(this.IN, 'auth', this.getLinkedInUserInfo);
console.log('end of constructor')
}
linkedInAuthorization(){
this.IN.User.authorize();
console.log('end of linkedInAuthorization service')
}
getLinkedInUserInfo() {
this.IN.API.Raw()
.url("/people/~:(firstName,lastName,emailAddress,industry,specialties,positions)?format=json")
.result((data:any) => {
localStorage.setItem('profile', JSON.stringify(data));
this.userProfile = data;
});
console.log('end of getLinkedInUserInfo service');
this.AuthLinkedInOnGlx
}
AuthLinkedInOnGlx (){
}
}