2017-10-29 84 views
6

Opis: Robię reagować natywną aplikację, gdzie mam listę użytkowników GitHub, że mam następujące i chcę zaimplementować funkcjonalność unfollow i odświeżyć lista.Fetch API powrocie starych danych w reagują rodzimy

Zrobiłem dwa asynchroniczne pomocniki do interakcji z interfejsem API github, jeden do przestał obserwować użytkownika (przez PUT) i drugi, aby uzyskać listę następnych (przez GET). Dodałem także detektor firebase na liście następujących elementów. Każde kolejne przejście do indywidualnego widoku profilu składa się z przycisku "Przestań obserwować". Po kliknięciu przycisku powinien przestać obserwować użytkownika, zaktualizować listę elementów w komponencie, a następnie wrócić do listy następujących elementów.

Problem Nie obserwowanie użytkownika działa zgodnie z oczekiwaniami, ale lista kolejnych widoków nadal zawiera starą listę. Mój kod wraca stare dane, mimo że github api zwraca nowe zaktualizowane dane, więc podejrzewam, że problem musi być taki, jak używam asynchronizacji/czekania.

Wykonałem nawet przycisk odświeżania, aby odświeżyć listę następnych, ale nowe dane są zwracane tylko czasami, np. 1/20.

UPDATE: Po przetestowaniu wielu scenariuszy, nie sądzę Firebase jest problem, ponieważ fetch zwraca te same stare dane. Myślę, że głównym problemem może być wywołanie fetch. Testowałem także pobieranie danych z Postmana i pobieranie poprawnych danych.

Wygląda na to, że fetch nie działa zgodnie z oczekiwaniami, ponieważ response.json() zawiera stare dane. Zrobiłem prosty tutaj jsfiddle (musisz dostarczyć swój własny token dostępu), który pokazuje, że get_following -> unfollow -> get_following działa poprawnie, również następujące dane zostały zmodyfikowane. Jednak w mojej aplikacji fetch zwraca te same stare dane przed unfollow, mimo że interfejs użytkownika github wyświetla zmianę, a Postman zwraca zmienione dane. Też trochę zaktualizowałem kod.

Kod

Lista poniższych

/** 
    * Listens for any changes on the database and updates the 
    * dataSource accordingly. 
    * @param {Firebase Object} ref 
    */ 
    _listenForData(ref) { 
     ref.on('value', (snapshot) => { 
      this.setState({ 
       dataSource: snapshot.val() 
      }, 
      this.setState({ 
       isLoading: false, 
      })); 
     }); 
    } 

    componentDidMount() { 
     // Sets up the listener for realtime changes. 
     GithubApi.get_followings(this.ref) 
     .then(_ => this._listenForData(this.ref)); 
    } 

indywidualnego użytkownika z obserwuj przycisku

async unfollow() { 

    try { 
     let success = await GithubApi.unfollow_user(this.state.login); 
     console.log('unfollowed user'); 
     console.log(success); 
     if (success) { 
      // Updates database after unfollowing 
      console.log('update followings') 
      await GithubApi.get_followings(this.ref); 
      return true; 
     } 
    } catch (error) { 
     console.error(error); 
     return false; 
    } 
} 

render() { 
    const { goBack } = this.props.navigation; 
    return (
     <Button 
      title='Unfollow' 
      onPress={ 
       () => this.unfollow().then(_ => goBack()) 
      } 
     /> 
    ) 
} 

Github Api Pomocnicy

const GithubApi = { 
    url: 'https://api.github.com/', 
    access_token: ..., 

    /** 
    * An asychronous helper function to grab data from github 
    * given an url and add data the firebase. 
    * 
    * @param {string} url 
    * @param {Firebase Object} firebaseRef 
    */ 
    _get_data_from_github_with_firebase: async function(url, firebaseRef) { 
     try { 
      let response = await fetch(url); 
      let responseStatus = await response.status; 
      let responseJson = await response.json(); 
      if (responseStatus === 200) { 
       firebaseRef.set(responseJson, 
       (error) => { 
        if (error) { 
         console.log(error); 
         return false; 
        } else { 
         return true; 
        } 
       }); 
      } 
      return false; 
     } catch (error) { 
      return false; 
     } 
    }, 

    /** 
    * Gets the user's following data and adds it to the database. 
    * @param {Firebase Object} firebaseRef 
    */ 
    get_followings: async function(firebaseRef) { 
     return await this._get_data_from_github_with_firebase(
      this.url + 'user/following?' + this.access_token, 
      firebaseRef 
     ); 
    }, 

    unfollow_user: async function(username) { 
     try { 
      let url = this.url + 'user/following/' + username + '?' + this.access_token; 
      let response = await fetch(url, { method: 'DELETE'}); 
      let responseStatus = await response.status; 
      if (responseStatus === 204) { 
       return true; 
      } 
      return false; 
     } catch (error) { 
      return false; 
     } 
    }, 
+0

Jak wygląda "GithubApi.unfollow_user()"?/Co to jest 'this.state.login'? –

+0

@ArmanCharan, przykro mi Właśnie zaktualizowałem fragment kodu, aby dołączyć 'unfollower_user'. 'this.state.login' jest po prostu loginem użytkownika github. – ygongdev

+0

Całe dobre bracie. Czy chciałeś zdefiniować swój obiekt 'GithubApi' jako [Klasa] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)? Nigdy tak naprawdę nie widziałem nikogo, kto nazywa to "tym" na takim obiekcie wcześniej. –

Odpowiedz

2

Brakuje await wewnątrz _get_data_from_github_with_firebase. Spróbuj zmienić funkcję do tego:

_get_data_from_github_with_firebase: async function(url, firebaseRef) { 
     try { 
      let response = await fetch(url); 
      let responseStatus = await response.status; 
      let responseJson = await response.json(); 
      var result = false 
      if (responseStatus === 200) { 
       result = await firebaseRef.set(responseJson, 
       (error) => { 
        if (error) { 
         console.log(error); 
         return false; 
        } else { 
         return true; 
        } 
       }); 
      } 
      return result; 
     } catch (error) { 
      return false; 
     } 
    }, 

Uwaga Gorąco polecam użyć redux-saga do synchronizacji działań.

+0

Dzięki za twoje dane wejściowe, ale to też nie działa. Wynik również jest niezdefiniowany. – ygongdev

2

Czy jesteś przypadkiem byłym programistą C? Lub jesteś używany do przekazywania zmiennych przez odniesienie?

Myślę, że problemem jest to, że wewnątrz tej funkcji próbują zwrócić wartość przez odniesienie:

_get_data_from_github_with_firebase: async function(url, firebaseRef) { 
     try { 
      let response = await fetch(url); 
      let responseStatus = await response.status; 
      let responseJson = await response.json(); 
      var result = false 
      if (responseStatus === 200) { 
       result = await firebaseRef.set(responseJson, //You are executing a method by reference 
       (error) => { 
        if (error) { 
         console.log(error); 
         return false; 
        } else { 
         return true; 
        } 
       }); 
      } 
      return result; 
     } catch (error) { 
      return false; 
     } 
    }, 

Może bardziej ekspert JS deweloper mógł potwierdzić, czy to będzie działać, ale nie jestem przyzwyczajony do tego zrobić . Zmieniłbym podpis i po prostu zwrócę odpowiedźJson, zamiast próbować ustawić to w ten sposób.

Prawdopodobnie responseJson ma wartość wewnątrz tej funkcji, ale jest niezdefiniowana na zewnątrz.