Tutorial

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

Published on December 12, 2019
Default avatar

By Jacky Kimani

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.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Jacky Kimani

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel