Search code examples
javascriptreactjsapiasync-awaitinstagram-api

Instagram API, diplaying medias in react application


i am curently stuck in trying to set up an API on a react application. I did test my access token manually and it worked

https://api.instagram.com/v1/users/self/media/recent/?access_token=${accessToken}

but i am stuck when its about to import theses data into the statement of the app.

I check the architecture of the component adding manually url into the state and it worked out, so i get the probleme is probably in the function that i called diplayInsta() or in the util/insta.js method

const Insta = {
  getAccessToken() {
    //check if token exist
    if (accessToken) {
      return new Promise(resolve => resolve(accessToken));
    }
    //token ref
    return fetch(`https://api.instagram.com/oauth/authorize/? client_id=${client_id}&redirect_uri=${redirectURI}&response_type=token`, {
      method: 'POST'
    }).then(response => {
      return response.json();
    }).then(jsonResponse => {
      accessToken = jsonResponse.access_token;
    });
  },
  async display() {
    if (!accessToken) {
      this.getAccessToken();
    }
    try {
      let response = await fetch(`https://api.instagram.com/v1/users/self/media/recent/?access_token=${accessToken}`, {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${accessToken}`
        }
      });
      if (response.ok) {
        let jsonResponse = await response.json();
        let medias = jsonResponse.medias.data.map(media => ({
          id: media.data.id,
          image: media.data.images.standard_resolution.url
        }));
        return medias;
      }
      throw new Error('Request failed!');
    } catch (error) {
      console.log(error);
    }
  }
}

Here is my github link of the project where you will found the whole project. https://github.com/erwanriou/reactisbroken

I feel that its probably a very small mistake but i can't found where it is...I a good soul could help me to show me the good direction...

UPDATE - After the first answer i did actualise the code and i now resolve the access token part but still stuck in displaying it into the state of the App.js That is my major problem curently

here a screen of the working promise : https://www.dropbox.com/s/w9wh3h3m58r3n06/Promise.jpg?dl=0


Solution

  • Ok i found myself the solution. i put it here in case some of you are block in a similar problem :

    let accessToken;
    
    const Insta = {
      getAccessToken() {
        if (accessToken) {
          return new Promise(resolve => resolve(accessToken));
        }
        const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
        if (accessTokenMatch) {
          accessToken = accessTokenMatch[1];
          return accessToken;
        } else {
          const Url = `https://api.instagram.com/oauth/authorize/?client_id=${client_id}&redirect_uri=${redirectURI}&response_type=token`
          window.location = Url;
        }
      },
      async display() {
        if (!accessToken) {
          this.getAccessToken();
        }
        try {
          let response = await fetch(`https://api.instagram.com/v1/users/self/media/recent/?access_token=${accessToken}`, {
            method: 'GET'
          });
          if (response.ok) {
            console.log(response);
            let jsonResponse = await response.json();
            let medias = jsonResponse.data.map(media => ({
              id: media.id,
              image: media.images.standard_resolution.url
            }));
            return medias;
          }
          throw new Error('Request failed!');
        } catch (error) {
          console.log(error);
        }
      }
    }
    

    Now the part to import the fetch data into the state is :

    import React, { Component } from 'react';
    import './App.css';
    
    import Header from '../Header/Header.js';
    import MediaList from '../MediaList/MediaList.js';
    import Insta from '../../util/insta.js';
    
    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          mediasResult: [],
          accountName: 'Erwan'
        };
      }
    
    
      componentDidMount() {
        Insta.display().then(medias => this.setState({mediasResult: medias}));
      }
    
      render() {
        return (
          <div className="App">
            <Header accountName={this.state.accountName}/>
            <MediaList medias={this.state.mediasResult}/>
          </div>
        );
      }
    }
    
    export default App;
    

    In fact the componentDidMount save my day. Its that let you import fetch data into the state.