Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Cache API data using AsyncStorage React Native

Fairly new to React native and its concepts. I have been playing with RN for a while to create an application to fetch API data from

http://jsonplaceholder.typicode.com/photos

I have been looking into the documentation of AsyncStorage to implement how i can cache the API data so that upon terminating the application, it doesn't have to deal with fetching the data from web again and again, but wasn't successfully able to implement it.

It will be great if you can provide me help/suggestion based on it. I have included my source code for the 2 important files in my application, along with the a Test.js file with how i was trying to achieve.

import React, {Component} from 'react';
import { FlatList, View, Text, AsyncStorage, ActivityIndicator } from 'react-native';
import axios from 'axios';
import GalleryDetail from './GalleryDetail';

class GalleryList extends Component {

state = { photos: []};

componentDidMount() {
    axios.get('http://jsonplaceholder.typicode.com/photos')
    .then(response => this.setState({ photos: response.data }))
    .catch((error)=> console.warn("fetch Error: ", error));
}

getPhotos = async()=> {
    try {
        photos = await AsyncStorage.getItem('GalleryPhotos');
    }
    catch (error) {
        console.error(error);
    }
}

savePhotos(){
    AsyncStorage.setItem('GalleryPhotos', this.state.photos);
    console.log('works !');
}

renderPhoto = ({item})=> {
    return <GalleryDetail photo={item}/>
}

keyExtractor = (photo, index) => photo.id;

render () {

    if(!this.state.photos){
        return <ActivityIndicator/>;
    }

    return (
            <FlatList
                data = {this.state.photos}
                keyExtractor={this.keyExtractor}
                renderItem={this.renderPhoto}
            />
    );
}
}

export default GalleryList;

and GalleryDetail linked with GalleryList-

import React, {Component} from 'react';
import { Text, View, Image } from 'react-native';
 import Card from './Card';
 import CardSection from './CardSection';

const GalleryDetail = (props)=> {
     return (
        <Card>
            <CardSection style = {styles.headerContentStyle}>
                <Image
                    style={styles.thumbnailStyle}
                    source = {{ uri: props.photo.thumbnailUrl}}/>
                <Text style= {styles.textStyle}>{props.photo.title}    </Text>
            </CardSection>
        </Card>
    );
};

const styles = {
   headerContentStyle: {
       flexDirection: 'column',
       justifyContent: 'space-around'
   },

   thumbnailStyle: {
       height: 60,
       width: 60
   },

   textStyle: {
       fontSize: 12,
       //textAlign: 'right',
       flexDirection: 'row',
       justifyContent: 'flex-end',
       flex: 1,
       flexWrap: 'wrap',
       marginLeft: 5,
       marginRight: 5,
    }
    }

    export default GalleryDetail;

My method of trying was that- Upon launching the application, it will first look in asyncStorage, if it finds the data- it fetches from async otherwise going to the web,fetching and storing again for later use. I tried to implement somewhat like this in a separate file since i dint wanted to breakdown my already running app. The weird broken syntax is

State = {
        photos: []
    }

    componentDidMount() {

        // just a variable acting to fetch data from the stored keyvalue pair

        check = AsyncStorage.getItem("PhotosKey").then((response) => {
                     this.setState({"PhotosKey": response});
                      }).done();

        if(check) {
            console.log('Data was fetched!!!!!');
            check();
        }

        else {
            console.log("Data was not fetched!");

            var Data = axios.get('http://jsonplaceholder.typicode.com/photos').
            then(response => this.setState({ photos: response.data })).
            catch((error)=> console.warn("fetch Error: ", error));



        }
    }

Thanks in advance!

like image 783
Jatin Suneja Avatar asked Dec 31 '17 11:12

Jatin Suneja


People also ask

How do I store API data in AsyncStorage in React Native?

Using the setItem() method The setItem method saves data to the AsyncStorage and allows a key and a value. Here, the key is a string that the data or value is assigned to: // React Native component const value = { name: "Chimezie", job: "Software Developer" }; const storeUser = async () => { try { await AsyncStorage.

Where does AsyncStorage save data React Native?

On iOS, AsyncStorage is backed by native code that stores small values in a serialized dictionary and larger values in separate files. On Android, AsyncStorage will use either RocksDB or SQLite based on what is available.

How do you store login details in AsyncStorage in React Native?

To use AsyncStorage we need to install @react-native-async-storage/async-storage dependency. This command will copy all the dependency into your node_module directory. –save is optional, it is just to update the @react-native-community/async-storage dependency in your package. json file.

How do you use AsyncStorage in useEffect in React Native?

Open the App. js file and start by importing the following components. import React, {useState, useEffect} from 'react'; import { StyleSheet, View, Text, TextInput, TouchableOpacity, } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; Next, define a variable name STORAGE_KEY .


1 Answers

async componentDidMount() {
    const photoStorage = await AsyncStorage.getItem('GalleryPhotos')
    if(photoStorage) {
      try {
        const photoResp = await axios.get('http://jsonplaceholder.typicode.com/photos')
        const photoData = await JSON.stringify(photoResp.data)
        await AsyncStorage.setItem('GalleryPhotos', photoData);
      } catch(e) {
        console.warn("fetch Error: ", error)
     }
    .then(response => this.setState({ photos: response.data }))
   }
 }

later

getPhotos = async()=> {
  try {
      photos = JSON.parse(await AsyncStorage.getItem('GalleryPhotos'));
  }
  catch (error) {
    console.error(error);
  }
}
like image 138
Subramanya Chakravarthy Avatar answered Oct 19 '22 13:10

Subramanya Chakravarthy