// Tutorial //

How To Build an Image Slider using React, SuperAgent, and the Instagram API

Published on December 12, 2019
Default avatar
By Jacky Kimani
Developer and author at DigitalOcean.
How To Build an Image Slider using React, SuperAgent, and the Instagram API

This tutorial is out of date and no longer maintained.

Introduction

In this tutorial you will build an image slider with images fetched from Instagram using SuperAgent.

There are many different libraries that can be used to make Ajax calls. Fetch API, Axios, Request, jQuery $.ajax and SuperAgent are some of the most popular ways to fetch data from an API.

Specifically, you will create an image slider using the reactjs JavaScript library. It will display images from Instagram that are fetched using the SuperAgent Ajax request library.

Prerequisites

Once you have those requirements installed, you can begin by setting up your project workspace.

Step 1 – Setting Up the Project

The create-react-app command is a convenient way to set up your project. It will help configure dependencies and leave you to focus on the React side of things.

Start off by running the command on your terminal:

  1. npx create-react-app image_slider

The result will be a project folder named image_slider (to use another name, simply replace image_slider on the terminal with your preferred name). The project folder will contain important files including package.json, node_modules and your src folder, which is where your app files will live.

In your terminal, change into the project folder and start the app to make sure everything works perfectly by running the command below:

  1. cd image_slider
  2. npm start

Note: If you have yarn installed, your message may instruct you to use yarn start instead of npm start. If you prefer to have npm instructions, it is possible to use --use-npm flag when creating your project. You can use either yarn or npm for this tutorial.

This should open the URL http://localhost:3000/ on your browser. Any changes that you make to the React files will automatically make the page reload in the browser.

Step 2 – Setting Up React

All of the React dependencies that you need are already installed for you. For this tutorial, only one file will be edited in the project. Feel free to separate the various components that you create in seperate files if you prefer. If you do, ensure to export and import them correctly.

To get started, edit App.js and replace all of the child elements in the <header></header> tag with a <h1></h1> element with “Welcome to My Instagram” text. You can also remove the logo import.

At this point, your App.js file should look like this:

src/App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">Welcome to My Instagram</h1>
      </header>
    </div>
  );
}

export default App;

Notice that the browser automatically reloads when you make changes to your file and save it.

Step 3 – Setting Up SuperAgent

As defined on its documentation, SuperAgent is a light-weight, progressive AJAX API crafted for flexibility, readability, and a low learning curve.

A request made should have the method or action that you’d like to perform, followed by a .then() or .end() function to perform operations on/with the response. You can include a .catch method for error handling but this is optional.

A GET request would then look like this:

request
  .get('/getsomedata')
  .then((res) => {
    console.log(res)
  }
  .catch((err) => {
    console.log(err)
  }

Start off by installing SuperAgent. In your terminal, run the following:

  1. npm install supertest

Next, import it on your App.js file and edit the file to look like the following:

src/App,js
import React, { Component } from 'react';
import request from 'superagent';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      photos: []
    }
  }

  componentWillMount() {
    this.fetchPhotos();
  }

  fetchPhotos() {
    request
      .get('https://api.instagram.com/v1/users/self/media/recent/?access_token=ACCESS-TOKEN')
      .then((res) => {
        this.setState({
          photos: res.body.data
        })
      })
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to My Instagram</h1>
        </header>
        <div>
          {console.log(this.state.photos)}
        </div>
      </div>
    );
  }
}

export default App;

The function named fetchPhotos is responsible for fetching data from Instagram. Once it GETs the data, it is stored in an array called photos which is in the state. The fetchPhotos function is called right before the component mounts using componentWillMount. For now, you’ll be logging the array to see whether you have fetched the data. You have not done any authentication yet so you shouldn’t be able to see anything, instead it should give you a 400 error message.

Step 4 – Generating an Instagram Token

The Instagram API will provide the photos to display with the slider you’re creating. Since you’re only working on the client side and not focusing on how to use the Instagram API, you don’t have to go through the authentication process to get your access token. However, if you’d like to learn more about how to use the Instagram API, you can go through their documentation.

You can generate a token using http://instagram.pixelunion.net.

Be sure to have the token in a .env file to avoid sharing it.

Step 5 – Creating the Image Slider

Displaying the images

The photos that you fetched are contained in an array but you need to display each one of them as a single photo. Therefore, you’ll need to write a map function to loop through the array and return your photos which will all be displayed on your page.

Before adding your photos onto your page, you can try logging the photo onto the browser’s console by adding this line inside the map function {console.log(photo)}. This will give you an object that contains a number of attributes, a few being images, captions, created_at date, likes, comments, people tagged on the photo etc.

Your new function will be inside a new div under your header and should look like this:

src/App.js
<div>
  {this.state.photos.map((photo, key) => {
    return (
      <div key={photo.id}>
        <img src={photo.images.standard_resolution.url} alt={photo.caption}/>
      </div>
    )
  })}
</div>

The slider will also display the captions for photos on the bottom of the photos. To do this, add another div below the image tag. Finally to avoid any errors in case the photo has no caption on Instagram, add a conditional that returns an empty string:

src/App.js
<div style={{width:'600px', margin: '24px auto', fontStyle: 'italic'}}>
  {photo.caption !== null ? photo.caption.text : ''}
</div>

Adding the slider arrows

So far all the photos fetched from the Instagram API will be displayed on the same page together. The next step is to display each photo separately and add navigation from one photo to the other.

Arrows are a useful way to navigate through the slider. For this functionality, include two arrows as separate components like this:

src/App.js
const BackArrow = () => (
  <div style={{fontSize: '2em', marginRight: '12px'}}>
    <i className="fa fa-angle-left fa-2x" aria-hidden="true"></i>
  </div>
)

const NextArrow = () => (
  <div style={{fontSize: '2em', marginLeft: '12px'}}>
    <i className="fa fa-angle-right fa-2x" aria-hidden="true"></i>
  </div>
)

Create React App does not have the script you need to use font awesome icons so you will need to run npm install font-awesome to add it to the project then import 'font-awesome/css/font-awesome.css' to include your icons.

Adding slide count to state

What you have now is all the components you’ll need but the arrows are not functional and all your photos are still visible on your page.

Add slideCount to your state to keep track of which photo you are on. slideCount will simply be an integer which is initially set at 0 and is incremented each time you click on the next arrow and decremented when you click on the previous arrow.

src/App.js
  constructor(props) {
    super(props);
    this.state = {
      photos: [],
      slideCount: 0
    }
  }

To display a single photo at a time, check the index of the photo and display the photo that matches the slide count on your state. This should be inside your map function like this:

src/App.js
<div className="App">
  <header className="App-header">
    <img src={logo} className="App-logo" alt="logo" />
    <h1 className="App-title">Welcome to My Instagram</h1>
  </header>
  <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: '30px'}}>
    {this.state.slideCount !== 0 ? <BackArrow previousImage={this.previousImage}/> : ''}
    {this.state.photos.map((photo, key) => {
      if (this.state.photos.indexOf(photo) === this.state.slideCount) {
        return (
          <div key={photo.id} style={{margin: '0 auto'}}>
            <img src={photo.images.standard_resolution.url} alt=''/>
            <div style={{width:'600px', margin: '24px auto', fontStyle: 'italic'}}>
              {photo.caption !== null ? photo.caption.text : ''}
             </div>
          </div>
        )
      }
      return ''
    })}
    {this.state.slideCount !== (this.state.photos.length - 1) ? <NextArrow nextImage={this.nextImage}/> : ''}
  </div>
</div>

You’re including an if statement when calling your BackArrow component because you don’t want to see it when you’re on the first photo. Similarly, you don’t want to see the NextArrow when you’re on the very last photo.

At this point since your state is 0, the browser should display one image (the very latest on the Instagram account) and the next arrow.

Making the arrows functional

To get the arrows working, create two functions that will change the current photo that is being viewed. The functions will either increment the state’s slideCount or decrement it to change the photo being displayed:

src/App.js
nextImage() {
  this.setState({ slideCount: this.state.slideCount + 1 })
}

previousImage() {
  this.setState({ slideCount: this.state.slideCount - 1 })
}

You’ll also need to add an event handler that calls these functions whenever the arrows are clicked. Add the onClick event to the two arrow components you created.

src/App.js
const BackArrow = (props) => (
  <div onClick={props.previousImage} style={{fontSize: '2em', marginRight: '12px'}}>
    <i className="fa fa-angle-left fa-2x" aria-hidden="true"></i>
  </div>
)

const NextArrow = (props) => (
  <div onClick={props.nextImage} style={{fontSize: '2em', marginLeft: '12px'}}>
    <i className="fa fa-angle-right fa-2x" aria-hidden="true"></i>
  </div>
)

Remember to pass the two functions as props from the parent component.

src/App.js
<BackArrow previousImage={this.previousImage}/>
<NextArrow nextImage={this.nextImage}/>

To have access to the functions you’ll need to bind the functions to the component instance (this)

src/App.js
this.nextImage = this.nextImage.bind(this);
this.previousImage = this.previousImage.bind(this);

At this point, you should have a fully functional image slider.

Conclusion

In this tutorial, you learned how to use SuperAgent as a request library in combination with React to build an interactive image slider. With this set of tools in place, you could also expand the slider to incorporate other functionality like creating different custom URLs and use the post, delete and put methods to add, remove and edit images or captions respectively.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
Leave a comment