Arrow Function

Ce sujet est résolu
Default
,

Bonjour,

Bon d'accord, j'ai peut être clôturer mon premier sujet un peu trop tôt. Je m'explique, j'avais un soucis d'accès au this dans une fonction asynchrone, ce soucis là est régler, or, en remplaçant :

                    verifyPassword(this.state.username, this.state.password).then(function() => {
                      ls.get('koustConnecting').then((data) => {
                                                    this.setState(() => ({ connectStatus: data }))
                                                  });

Par

                    verifyPassword(this.state.username, this.state.password).then(() => {
                      ls.get('koustConnecting').then((data) => {
                                                    this.setState(() => ({ connectStatus: data }))
                                                  });

(Retrait du function pour utiliser une "Arrow function" à la place), et bien je me retrouve face à quelque chose d'incompréhensible. Avec la version "buguée", la première fonction de vérification s'éxécutait bien avant le

ls.get('koustConnecting').then((data) =>

Mais à présent, elle s'éxécutent toutes les deux presque simultanément, ce qui m'oblige à appuyer 2 fois sur mon bouton pour changer le statut, il y a t-il une autre solution? J'ai essayer pourtant d'y mettre un timer mais rien n'y fait.

Voici ma fonction verifyPassword :

function verifyPassword(userid, password){
     return fetch('https://xxxx.com/apex/rest/oauth2/acces_mobile?userid='.concat(userid.toUpperCase()), {
        method: 'GET'
     })
     .then((response) => response.json())
     .then((responseJson) => {
        var ls = require('react-native-local-storage');
        var data = responseJson.items;

        var l_salt = "XVXXX24ECXXHDCQHSS6XXXQTJSANT3";
        var custom_hash = require('md5');

        try {
          var database_password = data[0].password;
          var crypted_password = custom_hash(password.concat(l_salt.substr(9,13), userid.toUpperCase(), l_salt.substr(3, 10))).toUpperCase();

          if(crypted_password === database_password){
            ls.save('koustConnecting', 'true');
          } else {
            ls.save('koustConnecting', 'false');
          }
        } catch (e) {
          console.log(e)
          return false;
        }

     })
     .catch((error) => {
        console.error(error);
     });

};

PS : Lien du dernier topic : https://www.grafikart.fr/forum/topics/31381

Excusez moi de créer 2 topics pour le même sujet.

Merci !

3 Réponse

7314
,

Si ton package react-native-local-storage est bien https://www.npmjs.com/package/react-native-local-storage, tu peux voir que ls.save() retourne une promise. Hors dans ta fonction verifyPassword tu n'attends pas qu'elle soit résolue. Normalement, quelque chose comme ceci devrait corriger le problème.

function verifyPassword(userid, password){
     return fetch('https://xxxx.com/apex/rest/oauth2/acces_mobile?userid='.concat(userid.toUpperCase()), {
        method: 'GET'
     })
     .then((response) => response.json())
     .then((responseJson) => {
        var ls = require('react-native-local-storage');
        var data = responseJson.items;

        var l_salt = "XVXXX24ECXXHDCQHSS6XXXQTJSANT3";
        var custom_hash = require('md5');

        try {
          var database_password = data[0].password;
          var crypted_password = custom_hash(password.concat(l_salt.substr(9,13), userid.toUpperCase(), l_salt.substr(3, 10))).toUpperCase();

          return ls.save('koustConnecting', JSON.stringify(crypted_password === database_password));
        } catch (e) {
          throw e
        }
     })
     .catch((error) => {
        console.error(error);
     });
};

Ensuite je ferai quelque chose comme cela

verifyPassword(this.state.username, this.state.password)
  .then(() => ls.get('koustConnecting'))
  .then((data) => {
     this.setState(() => ({ connectStatus: data }))
  });
Default
,

Update :

J'ai trouvé une solution, mais engendrée une autre, la même que mon dernier topic, mais j'ai beau essayé d'utiliser les conseils que j'avais eu, ça ne fonctionne absolument pas..

Donc, j'ai procédé ainsi :

async function connexion(username, entered_password){
  var ls = require('react-native-local-storage');

  var result = await verifyPassword(username, entered_password).then(() => {
    ls.get('koustConnecting').then((data) => {
                                  this.setState(() => ({ connectStatus: data }));
                                  console.log(this.state.data);
                                });
  });
}

J'utilise donc une fonction asynchrone que j'appelle de cette façon :

                  try {
                    connexion(this.state.username, this.state.password);
                  } catch (error) {
                    console.log("Error retrieving data" + error);
                  }

Maiiiis, j'obtiens cette erreur :

[Unhandled promise rejection: TypeError: _this3.setState is not a function. (In '_this3.setState(function () {]
* class\Login.js:147:48 in <unknown>
- node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
- node_modules\promise\setimmediate\core.js:123:25 in <unknown>
- ... 8 more stack frames from framework internals

L'origine est bien sûr que je ne peux pas accéder à this dans une fonction asynchrone.. Or, si je return data, j'aurais un Promise en retour, je vois pas comment je peux récupérer cette satanée valeur pour la mettre en state :(

Merci.

Default
,

C'était ça ! Merci.