This tutorial is out of date and no longer maintained.
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.
Once you have those requirements installed, you can begin by setting up your project workspace.
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:
- 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:
- cd image_slider
- 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.
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:
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.
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:
- npm install supertest
Next, import it on your App.js
file and edit the file to look like the following:
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.
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.
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:
<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:
<div style={{width:'600px', margin: '24px auto', fontStyle: 'italic'}}>
{photo.caption !== null ? photo.caption.text : ''}
</div>
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:
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.
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.
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:
<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.
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:
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.
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.
<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
)
this.nextImage = this.nextImage.bind(this);
this.previousImage = this.previousImage.bind(this);
At this point, you should have a fully functional image slider.
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.
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!