Navigate from within Promise callback












0















I am just starting out with React Native and am running into the following problem when trying to navigate from within a Promise callback.



Here is the following code I am trying to run. I want to navigate to another screen if the http request returns that the user's login information is correct.



login() {
axios({
method: 'post',
url: `${Globals.WebAPI}/api/authentication/login`,
data: {
username: this.state.username,
password: this.state.password
}
})
.then(function(response) {
console.log(response.data.token)
AsyncStorage.setItem("AuthToken", response.data.token);
this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
})
.catch(function(error) {
console.log(error);
});
}



render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={this.goToDetails}
/>
<Button
title="Signup"
onPress={this.goToSignup}
/>
<Text>Username</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({username: text})}
value={this.state.username}
/>
<Text>Password</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({password: text})}
value={this.state.password}
/>
<Button
title="Login"
onPress={this.login}
/>
</View>
)};


This is the error that I am getting from this function:



undefined is not an object (evaluating 'this.props.navigation')


I feel like this error is coming from me not fully understanding the props usage, so I am hoping that this answer helps solidify my knowledge of what's going on in React Native.



Thanks in advance










share|improve this question























  • here .then(function(response) { console.log(response.data.token) AsyncStorage.setItem("AuthToken", response.data.token); this.props.navigation.navigate('PictureDetails', {base64: photo.base64}); }) your this pointer to class instance is lost. So you can bind the this with arrow function.

    – Karen Grigoryan
    Nov 19 '18 at 22:19











  • For more information on what @KarenGrigoryan is describing, see here: stackoverflow.com/questions/30486345/…. To elaborate on the solution: onPress={this.login.bind(this)} or onPress={x=> this.login()} either of these methods should work.

    – David784
    Nov 19 '18 at 22:37











  • @SamMallabone instead of then(function(response) { ... use arrow function then((response) => {...

    – Karen Grigoryan
    Nov 19 '18 at 22:38











  • Ah, @KarenGrigoryan and I were actually talking about two different issues. She is pointing out that the function this will obscure the class level this. I believe you will also need to bind the class this in your onPress event.

    – David784
    Nov 19 '18 at 22:43











  • @KarenGrigoryan that works perfectly, thanks! If you want to convert that to an answer I can mark it as correct.

    – Sam Mallabone
    Nov 19 '18 at 22:43
















0















I am just starting out with React Native and am running into the following problem when trying to navigate from within a Promise callback.



Here is the following code I am trying to run. I want to navigate to another screen if the http request returns that the user's login information is correct.



login() {
axios({
method: 'post',
url: `${Globals.WebAPI}/api/authentication/login`,
data: {
username: this.state.username,
password: this.state.password
}
})
.then(function(response) {
console.log(response.data.token)
AsyncStorage.setItem("AuthToken", response.data.token);
this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
})
.catch(function(error) {
console.log(error);
});
}



render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={this.goToDetails}
/>
<Button
title="Signup"
onPress={this.goToSignup}
/>
<Text>Username</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({username: text})}
value={this.state.username}
/>
<Text>Password</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({password: text})}
value={this.state.password}
/>
<Button
title="Login"
onPress={this.login}
/>
</View>
)};


This is the error that I am getting from this function:



undefined is not an object (evaluating 'this.props.navigation')


I feel like this error is coming from me not fully understanding the props usage, so I am hoping that this answer helps solidify my knowledge of what's going on in React Native.



Thanks in advance










share|improve this question























  • here .then(function(response) { console.log(response.data.token) AsyncStorage.setItem("AuthToken", response.data.token); this.props.navigation.navigate('PictureDetails', {base64: photo.base64}); }) your this pointer to class instance is lost. So you can bind the this with arrow function.

    – Karen Grigoryan
    Nov 19 '18 at 22:19











  • For more information on what @KarenGrigoryan is describing, see here: stackoverflow.com/questions/30486345/…. To elaborate on the solution: onPress={this.login.bind(this)} or onPress={x=> this.login()} either of these methods should work.

    – David784
    Nov 19 '18 at 22:37











  • @SamMallabone instead of then(function(response) { ... use arrow function then((response) => {...

    – Karen Grigoryan
    Nov 19 '18 at 22:38











  • Ah, @KarenGrigoryan and I were actually talking about two different issues. She is pointing out that the function this will obscure the class level this. I believe you will also need to bind the class this in your onPress event.

    – David784
    Nov 19 '18 at 22:43











  • @KarenGrigoryan that works perfectly, thanks! If you want to convert that to an answer I can mark it as correct.

    – Sam Mallabone
    Nov 19 '18 at 22:43














0












0








0








I am just starting out with React Native and am running into the following problem when trying to navigate from within a Promise callback.



Here is the following code I am trying to run. I want to navigate to another screen if the http request returns that the user's login information is correct.



login() {
axios({
method: 'post',
url: `${Globals.WebAPI}/api/authentication/login`,
data: {
username: this.state.username,
password: this.state.password
}
})
.then(function(response) {
console.log(response.data.token)
AsyncStorage.setItem("AuthToken", response.data.token);
this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
})
.catch(function(error) {
console.log(error);
});
}



render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={this.goToDetails}
/>
<Button
title="Signup"
onPress={this.goToSignup}
/>
<Text>Username</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({username: text})}
value={this.state.username}
/>
<Text>Password</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({password: text})}
value={this.state.password}
/>
<Button
title="Login"
onPress={this.login}
/>
</View>
)};


This is the error that I am getting from this function:



undefined is not an object (evaluating 'this.props.navigation')


I feel like this error is coming from me not fully understanding the props usage, so I am hoping that this answer helps solidify my knowledge of what's going on in React Native.



Thanks in advance










share|improve this question














I am just starting out with React Native and am running into the following problem when trying to navigate from within a Promise callback.



Here is the following code I am trying to run. I want to navigate to another screen if the http request returns that the user's login information is correct.



login() {
axios({
method: 'post',
url: `${Globals.WebAPI}/api/authentication/login`,
data: {
username: this.state.username,
password: this.state.password
}
})
.then(function(response) {
console.log(response.data.token)
AsyncStorage.setItem("AuthToken", response.data.token);
this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
})
.catch(function(error) {
console.log(error);
});
}



render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={this.goToDetails}
/>
<Button
title="Signup"
onPress={this.goToSignup}
/>
<Text>Username</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({username: text})}
value={this.state.username}
/>
<Text>Password</Text>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({password: text})}
value={this.state.password}
/>
<Button
title="Login"
onPress={this.login}
/>
</View>
)};


This is the error that I am getting from this function:



undefined is not an object (evaluating 'this.props.navigation')


I feel like this error is coming from me not fully understanding the props usage, so I am hoping that this answer helps solidify my knowledge of what's going on in React Native.



Thanks in advance







javascript react-native react-navigation






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 22:09









Sam MallaboneSam Mallabone

2161313




2161313













  • here .then(function(response) { console.log(response.data.token) AsyncStorage.setItem("AuthToken", response.data.token); this.props.navigation.navigate('PictureDetails', {base64: photo.base64}); }) your this pointer to class instance is lost. So you can bind the this with arrow function.

    – Karen Grigoryan
    Nov 19 '18 at 22:19











  • For more information on what @KarenGrigoryan is describing, see here: stackoverflow.com/questions/30486345/…. To elaborate on the solution: onPress={this.login.bind(this)} or onPress={x=> this.login()} either of these methods should work.

    – David784
    Nov 19 '18 at 22:37











  • @SamMallabone instead of then(function(response) { ... use arrow function then((response) => {...

    – Karen Grigoryan
    Nov 19 '18 at 22:38











  • Ah, @KarenGrigoryan and I were actually talking about two different issues. She is pointing out that the function this will obscure the class level this. I believe you will also need to bind the class this in your onPress event.

    – David784
    Nov 19 '18 at 22:43











  • @KarenGrigoryan that works perfectly, thanks! If you want to convert that to an answer I can mark it as correct.

    – Sam Mallabone
    Nov 19 '18 at 22:43



















  • here .then(function(response) { console.log(response.data.token) AsyncStorage.setItem("AuthToken", response.data.token); this.props.navigation.navigate('PictureDetails', {base64: photo.base64}); }) your this pointer to class instance is lost. So you can bind the this with arrow function.

    – Karen Grigoryan
    Nov 19 '18 at 22:19











  • For more information on what @KarenGrigoryan is describing, see here: stackoverflow.com/questions/30486345/…. To elaborate on the solution: onPress={this.login.bind(this)} or onPress={x=> this.login()} either of these methods should work.

    – David784
    Nov 19 '18 at 22:37











  • @SamMallabone instead of then(function(response) { ... use arrow function then((response) => {...

    – Karen Grigoryan
    Nov 19 '18 at 22:38











  • Ah, @KarenGrigoryan and I were actually talking about two different issues. She is pointing out that the function this will obscure the class level this. I believe you will also need to bind the class this in your onPress event.

    – David784
    Nov 19 '18 at 22:43











  • @KarenGrigoryan that works perfectly, thanks! If you want to convert that to an answer I can mark it as correct.

    – Sam Mallabone
    Nov 19 '18 at 22:43

















here .then(function(response) { console.log(response.data.token) AsyncStorage.setItem("AuthToken", response.data.token); this.props.navigation.navigate('PictureDetails', {base64: photo.base64}); }) your this pointer to class instance is lost. So you can bind the this with arrow function.

– Karen Grigoryan
Nov 19 '18 at 22:19





here .then(function(response) { console.log(response.data.token) AsyncStorage.setItem("AuthToken", response.data.token); this.props.navigation.navigate('PictureDetails', {base64: photo.base64}); }) your this pointer to class instance is lost. So you can bind the this with arrow function.

– Karen Grigoryan
Nov 19 '18 at 22:19













For more information on what @KarenGrigoryan is describing, see here: stackoverflow.com/questions/30486345/…. To elaborate on the solution: onPress={this.login.bind(this)} or onPress={x=> this.login()} either of these methods should work.

– David784
Nov 19 '18 at 22:37





For more information on what @KarenGrigoryan is describing, see here: stackoverflow.com/questions/30486345/…. To elaborate on the solution: onPress={this.login.bind(this)} or onPress={x=> this.login()} either of these methods should work.

– David784
Nov 19 '18 at 22:37













@SamMallabone instead of then(function(response) { ... use arrow function then((response) => {...

– Karen Grigoryan
Nov 19 '18 at 22:38





@SamMallabone instead of then(function(response) { ... use arrow function then((response) => {...

– Karen Grigoryan
Nov 19 '18 at 22:38













Ah, @KarenGrigoryan and I were actually talking about two different issues. She is pointing out that the function this will obscure the class level this. I believe you will also need to bind the class this in your onPress event.

– David784
Nov 19 '18 at 22:43





Ah, @KarenGrigoryan and I were actually talking about two different issues. She is pointing out that the function this will obscure the class level this. I believe you will also need to bind the class this in your onPress event.

– David784
Nov 19 '18 at 22:43













@KarenGrigoryan that works perfectly, thanks! If you want to convert that to an answer I can mark it as correct.

– Sam Mallabone
Nov 19 '18 at 22:43





@KarenGrigoryan that works perfectly, thanks! If you want to convert that to an answer I can mark it as correct.

– Sam Mallabone
Nov 19 '18 at 22:43












2 Answers
2






active

oldest

votes


















1














This part loses this binding:



  .then(function(response) { 
console.log(response.data.token)
AsyncStorage.setItem("AuthToken", response.data.token);
this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
})


so when you call this.props.navigation.navigate(, this is undefined, which is what your error tells you.



The easiest fix is to convert regular function to an arrow function, which lexically binds the this to surrounding context's this value.



  .then((response) => { 
console.log(response.data.token)
AsyncStorage.setItem("AuthToken", response.data.token);
this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
})


More info here






share|improve this answer































    -2














    I guess you didn't create a Navigation object using react-navigation library.
    I need to see the whole file of this code to make sure what the reason is.






    share|improve this answer
























    • Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

      – bcperth
      Nov 19 '18 at 22:41











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383351%2fnavigate-from-within-promise-callback%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    This part loses this binding:



      .then(function(response) { 
    console.log(response.data.token)
    AsyncStorage.setItem("AuthToken", response.data.token);
    this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
    })


    so when you call this.props.navigation.navigate(, this is undefined, which is what your error tells you.



    The easiest fix is to convert regular function to an arrow function, which lexically binds the this to surrounding context's this value.



      .then((response) => { 
    console.log(response.data.token)
    AsyncStorage.setItem("AuthToken", response.data.token);
    this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
    })


    More info here






    share|improve this answer




























      1














      This part loses this binding:



        .then(function(response) { 
      console.log(response.data.token)
      AsyncStorage.setItem("AuthToken", response.data.token);
      this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
      })


      so when you call this.props.navigation.navigate(, this is undefined, which is what your error tells you.



      The easiest fix is to convert regular function to an arrow function, which lexically binds the this to surrounding context's this value.



        .then((response) => { 
      console.log(response.data.token)
      AsyncStorage.setItem("AuthToken", response.data.token);
      this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
      })


      More info here






      share|improve this answer


























        1












        1








        1







        This part loses this binding:



          .then(function(response) { 
        console.log(response.data.token)
        AsyncStorage.setItem("AuthToken", response.data.token);
        this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
        })


        so when you call this.props.navigation.navigate(, this is undefined, which is what your error tells you.



        The easiest fix is to convert regular function to an arrow function, which lexically binds the this to surrounding context's this value.



          .then((response) => { 
        console.log(response.data.token)
        AsyncStorage.setItem("AuthToken", response.data.token);
        this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
        })


        More info here






        share|improve this answer













        This part loses this binding:



          .then(function(response) { 
        console.log(response.data.token)
        AsyncStorage.setItem("AuthToken", response.data.token);
        this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
        })


        so when you call this.props.navigation.navigate(, this is undefined, which is what your error tells you.



        The easiest fix is to convert regular function to an arrow function, which lexically binds the this to surrounding context's this value.



          .then((response) => { 
        console.log(response.data.token)
        AsyncStorage.setItem("AuthToken", response.data.token);
        this.props.navigation.navigate('PictureDetails', {base64: photo.base64});
        })


        More info here







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 '18 at 22:49









        Karen GrigoryanKaren Grigoryan

        2,7781922




        2,7781922

























            -2














            I guess you didn't create a Navigation object using react-navigation library.
            I need to see the whole file of this code to make sure what the reason is.






            share|improve this answer
























            • Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

              – bcperth
              Nov 19 '18 at 22:41
















            -2














            I guess you didn't create a Navigation object using react-navigation library.
            I need to see the whole file of this code to make sure what the reason is.






            share|improve this answer
























            • Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

              – bcperth
              Nov 19 '18 at 22:41














            -2












            -2








            -2







            I guess you didn't create a Navigation object using react-navigation library.
            I need to see the whole file of this code to make sure what the reason is.






            share|improve this answer













            I guess you didn't create a Navigation object using react-navigation library.
            I need to see the whole file of this code to make sure what the reason is.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 19 '18 at 22:34









            James ChanJames Chan

            1




            1













            • Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

              – bcperth
              Nov 19 '18 at 22:41



















            • Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

              – bcperth
              Nov 19 '18 at 22:41

















            Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

            – bcperth
            Nov 19 '18 at 22:41





            Welcome to Stackoverflow. It better you seek clarification in comments rather than as a reply. Then when all is clear, post a reply.

            – bcperth
            Nov 19 '18 at 22:41


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383351%2fnavigate-from-within-promise-callback%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

            A Topological Invariant for $pi_3(U(n))$