Home » vue » How to call to external function in axios.spread function in VueJS?

How to call to external function in axios.spread function in VueJS?

Posted by: admin November 26, 2021 Leave a comment

Questions:

I can’t call any external functions inside an axios promise. My error is

[Uncaught (in promise) TypeError: this.showNotification is not a function]

showNotification is an external function inside mixin but i can’t call it in userCompInfo function

var mixin = {
 methods: {
//function to get all user info
userInfo:function(){
    //alert(localStorage.getItem("sessionKey"))
    if(localStorage.getItem("sessionKey")==null)
        session = "null";
    else
        session= localStorage.getItem("sessionKey");

    return axios.post("/api/user/info",{
         user_id:localStorage.getItem("userId"),
         session_key:session             
    });

},
//function to get all competition info
compInfo:function()
{   //calling API competition info to get the avaliable competition for now
    return axios.post("/api/competition/info",{
        lang:source.lang                
    });

},
userCompInfo:function()
{
    axios.all([this.userInfo(),this.compInfo()])
    .then(axios.spread(function (user, comp){
        if(comp.data.result.errorcode == 0)
        {
            source.competition = comp.data.competiton_detail; 

        }   

        //set the user id in local storage
        localStorage.setItem("userId",user.data.user_info.user_id);
        //check on session key to save it in local storage
        if(user.data.user_info.session_key != "") // for testing
            localStorage.setItem("sessionKey",user.data.user_info.session_key);

        // get user data successfuly
        if(user.data.result.errorcode == 0)
        {   //set response data in user
            source.user = user.data.user_info;
            //to set this user status
            this.renderUserInfo();
            ///////////
            //source.competition.is_active=1;
            //check on user status to show notification
            if(source.user.vip && source.user.suspended)
            {
                this.showNotification(context.suspended_vip.title+" "+source.user.msisdn, context.suspended_vip.body,["btn_notifi_ok"]);
            }
            //check if this valid competition is active or not to show notification according to it and to user status
            if(source.competition.is_active==1)
            {   
                if(source.user.registered && newUser==1)
                {
                    this.showNotification(context.registered_firstTime.title, context.registered_firstTime.body, ["btn_notifi_start_play"]);
                }
                else if(source.user.free && source.user.newFreeUser) 
                {
                    this.showNotification(context.freeUser_firstTime.title, context.freeUser_firstTime.body, ["btn_notifi_start_play"]);
                }
            }
        }

    }));
},
// function to show notification modal
showNotification:function(title, body, buttons)
{
    //to hide all modal buttons first
    $("#notification").find(".btn").hide(); 
    //set the modal title  
    $("#notification_title").html(title);
    //set the modal body
    $("#notification_body").html(body);
    //for on buttons array to show all buttons that we want
    for(i=0;i<buttons.length;i++)
    {
        $("#notification").find("#"+buttons[i]).show();
    }   
    //to display modal 
    $("#notification").modal("show");
},
//function to show the current user statue VIP, registered,free or suspended
renderUserInfo:function()
{   // intialize all flags of user status to false
    source.user.vip = false;
    source.user.registered = false;
    source.user.free = false;
    //check on user mode and set the according flag to it to true
    if(source.user.sub_mode == "vip")
    {
        source.user.vip = true;
    }
    else if(source.user.sub_mode == "sub")
    {
        source.user.registered = true;
    }
    else
    {
        source.user.free = true;
    }   
},}}
Answers:

This is a very common mistake. this in userCompInfo doesn’t refer to the Vue because of they way you have written the callback.

In your code, make this change.

userCompInfo:function()
{
    axios.all([this.userInfo(),this.compInfo()])
    .then(axios.spread(function (user, comp){
        // a bunch of code...
    }.bind(this)));
},

Or

userCompInfo:function()
{
    let self = this;
    axios.all([this.userInfo(),this.compInfo()])
    .then(axios.spread(function (user, comp){
        // a bunch of code...
        self.showNotification(...)
        // some more code...
    }));
},

See How to access the correct this inside a callback?