J'essaie de créer une application mobile sur NativeScript
où j'ai créé une classe d'autorisation qui a une fonction login ()
qui a les codes suivants: XXX
J'ai inclus cette classe dans mon fichier main.js
sous le nom:
login() { this.$nitsEditorAuth .login(this.user) .then(() => { this.processing = false; this.$navigateTo(Home, { clearHistory: true }); }) .catch(() => { this.processing = false; this.alert( "Unfortunately we could not find your account." ); }); },
Et j'appelle cette fonction dans mes méthodes Vue
comme:
const nitsEditorAuth = new NitsEditorAuth(); Vue.prototype.$nitsEditorAuth = nitsEditorAuth;
Mais j'obtiens une erreur indiquant que:
TypeError: Impossible de lire la propriété 'then' de undefined. Cadre: fonction: 'login'
Aidez-moi avec ça. Merci.
4 Réponses :
Vous avez rompu la chaîne de promesses en ne renvoyant pas la promesse renvoyée par axios dans votre méthode login
(et l'appel interne à axios.get (apiUrl + 'user / log',
// a here points to a promise that will resolve to "Just the 2 of us" const a = Promise.resolve(1) .then(val => val + val) .then(val => `Just the ${val} of us`); a.then(val => console.log(val))
Renvoie les valeurs de alors les gestionnaires de promesses sont enchaînés , voir cet exemple:
return axios.post(authUrl...
Mais j'ai un autre appel axios après l'appel de authUrl. Est-ce bien de faire appel au premier?
@NitishKumar y ajoute également le retour. Sinon, enveloppez tout dans un bloc Promise
et appelez la résolution uniquement sur la promesse principale.
Ils sont alors imbriqués, ce qui sera retourné est ce que vous retournez du plus profond alors, vous devez vous assurer que tous les retours sont enchaînés
Une solution simple consisterait simplement à emballer une promesse en dehors de la fonction. Et enlevez le reste. Par exemple.
javascript node.js vue.js nativescript nativescript-vue I'm trying to build a mobile application on NativeScript where I've created a class for authorization which has a login() function which has following codes: export default class NitsEditorAuth { //Finding logged-in user. isLoggedIn() { return store.getters.access_token ? true : false; } //For Login user login(user) { const postData = { grant_type: 'password', username: user.email, password: user.password, client_id: clientId, client_secret: clientSecret, scope: '', provider: provider } return new Promise(function (resolve, reject) { const authUser = {} axios.post(authUrl, postData).then(response => { if(response.status === 200) { authUser.access_token = response.data.access_token; authUser.refresh_token = response.data.refresh_token; axios.get(apiUrl + 'user/log', {headers: getHeader()}).then(response => { if(response.status === 200){ authUser.email = response.data.email; authUser.first_name = response.data.first_name; authUser.last_name = response.data.last_name; authUser.userRole = response.data.role; store.commit('save', authUser); resolve('Login successful') } }) } }) .catch((err) => { if(err.response.status === 401){ // this.error = err.response.data.message reject('Validation error') } else reject('Something went wrong') }) }) }
À des fins de conception, pour moi, c'est la solution la plus propre.
Oui, en faisant cela, vous vous assurez où jamais cette fonction est appelée, dites-lui d'attendre, elle a renvoyé une promesse. Une fois résolu, il appellera la méthode then ou catch s'il est rejeté.
Dans votre fonction de connexion, vous avez renvoyé une promesse dans le post-appel axios qui est de nature asynchrone. Votre fonction qui devrait renvoyer une promesse ne renvoie rien. Vous pouvez donc vous référer au code ci-dessous.
login() { let promise = new Promise(function(resolve, reject) { // your post call (dummy data) axios.post(authUrl, postData).then(response => { if(response.status === 200) { resolve('foo'); } else { reject('Login successful'); } }); return promise; }
J'espère que cela vous aidera.
Vous pouvez utiliser le modèle async / await.
async login(user) { const postData = { grant_type: 'password', username: user.email, password: user.password, client_id: clientId, client_secret: clientSecret, scope: '', provider: provider }; const authUser = {}; try { const postResponse = await axios.post(authUrl, postData); if (postResponse.status === 200) { authUser.access_token = response.data.access_token; authUser.refresh_token = response.data.refresh_token; const response = await axios.get(apiUrl + 'user/log', {headers: getHeader()}); if (response.status === 200) { authUser.email = response.data.email; authUser.first_name = response.data.first_name; authUser.last_name = response.data.last_name; authUser.userRole = response.data.role; store.commit('save', authUser); return 'Login successful'; } } return 'Validation error'; } catch(err) { if (err.response.status === 401){ return 'Validation error'; } return 'Something went wrong'; } }
Si vous pouvez utiliser async / await
, c'est le moyen le plus simple
La méthode
login
ne renvoie rien dansNitsEditorAuth
.@briosheje vous voulez dire la méthode
login
dans la classeNitsEditorAuth
?Oui, l'erreur est lancée ici à mon avis:
this. $ NitsEditorAuth .login (this.user)
<--- ici, .login renvoieundefined
car votre < code> axios n'est pas retourné, rien de plus que ça, vraiment, vous étiez très proche de la solution. Ajoutez simplementreturn
avantaxios
et cela devrait fonctionner comme prévu, même si je retournerais toujours unePromise
à la place (promesse personnalisée) à des fins de conception.