This tutorial will explain how to achieve to get YouTube instant search with API using ReactJs. You can find step by step tutorial to get the output. Demo and Download are available.
Before going to the tutorial, we have to setup the reactJs project. Follow the link to setup the reactjs project.
Folder Structure
Once the setup done using the above link you will see the below folder structure.
After creation, your project should look like this:
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── App.css
└── App.js
└── App.test.js
└── index.css
└── index.js
└── logo.svg
└── registerServiceWorker.js
Now we have to create the below listed folders inside the “src” folder.
- components
- css
- fonts
- services
Now create the below listed js files inside “components” folder
- App.js
- ListFilteredVideos.js
- NextPrevious.js
- Search.js
- VideoListLayout.js
Now download the bootstrap dependency files from Bootstrap website and place the files to their respected folders.
Now create the below js file inside “services” folder
- YouTubeGetData.js
Delete the below files from the “src” folder
- App.js
- App.css
- index.css
- logo.svg
Once the above steps are done, you will see the below folder structure
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── components
└── App.js
└── ListFilteredVideos.js
└── NextPrevious.js
└── Search.js
└── VideoListLayout.js
└── css
└── bootstrap.min.css
└── fonts
└── glyphicons-halflings-regular.eot
└── glyphicons-halflings-regular.svg
└── glyphicons-halflings-regular.ttf
└── glyphicons-halflings-regular.woff
└── glyphicons-halflings-regular.woff2
└── services
└── YouTubeGetData.js
└── App.test.js
└── index.js
└── registerServiceWorker.js
Now, Let’s start writing the code.
Open the “index.js” from “src” folder and copy past the below code.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Open the “App.js” from “src/components” folder and copy past the below code.
import React from 'react';
import ListFilteredVideos from './ListFilteredVideos.js';
import Search from './Search.js';
import NextPrevious from './NextPrevious.js';
import {youtubeApiServiceCall} from './../services/YouTubeGetData.js';
import '../css/bootstrap.min.css';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
posts: [],
filterText: 'HTML Tutorials',
nextPageToken:'',
prevPageToken:'',
pageToken:''
}
};
tokenUpdate(token) {
youtubeApiServiceCall(this.state.filterText, token).then((obj) => {
this.setState({
'posts':obj.posts,
'nextPageToken':obj.nextPageToken,
'prevPageToken':obj.prevPageToken
});
});
};
filterUpdate(value) {
this.setState({
filterText: value
});
youtubeApiServiceCall(this.state.filterText).then((obj) => {
this.setState({
'posts':obj.posts,
'nextPageToken':obj.nextPageToken,
'prevPageToken':obj.prevPageToken
});
});
};
componentDidMount() {
youtubeApiServiceCall(this.state.filterText).then((obj) => {
this.setState({
'posts':obj.posts,
'nextPageToken':obj.nextPageToken,
'prevPageToken':obj.prevPageToken
});
});
}
render() {
return (<div>
<Search filterVal={this.state.filterText} filterUpdate={this.filterUpdate.bind(this)}></Search>
<NextPrevious nextPageToken={this.state.nextPageToken} prevPageToken={this.state.prevPageToken} tokenUpdate={this.tokenUpdate.bind(this)}></NextPrevious>
<ListFilteredVideos posts={this.state.posts}></ListFilteredVideos>
</div>);
};
};
Open the “ListFilteredVideos.js” from “src/components” folder and copy past the below code.
import React from 'react';
import VideoListLayout from './VideoListLayout.js';
export default class ListFilteredVideos extends React.Component{
render(){
const {posts} = this.props;
return (<div className="panel-body">
{posts.map((post, i) =>
<VideoListLayout key={i} posts={post}> </VideoListLayout>
)}
</div>);
};
};
Open the “NextPrevious.js” from “src/components” folder and copy past the below code.
import React from 'react';
export default class NextPrevious extends React.Component{
render(){
var divStyle = {
textAlign: 'center'
};
const { nextPageToken, prevPageToken, tokenUpdate} = this.props;
return (
<div style={divStyle}>
<div className="btn-group">
{prevPageToken &&
<button type="button" id="pageTokenPrev" className="btn btn-default" onClick={() => {
tokenUpdate(prevPageToken)
}}>Prev</button>
}
{nextPageToken &&
<button type="button" id="pageTokenNext" className="btn btn-default" onClick={() => {
tokenUpdate(nextPageToken)
}}>Next</button>
}
</div>
</div>
);
};
};
Open the “Search.js” from “src/components” folder and copy past the below code.
import React from 'react';
export default class Search extends React.Component {
render() {
const { filterVal, filterUpdate} = this.props;
return (
<form>
<input
type='text'
ref='filterInput'
placeholder='Type to filter..'
// binding the input value to state
value={filterVal}
onChange={() => {
filterUpdate(this.refs.filterInput.value)
}}
/>
</form>
)
}
};
Open the “VideoListLayout.js” from “src/components” folder and copy past the below code.
import React from 'react';
export default class ListFilteredVideos extends React.Component{
render(){
const {posts} = this.props;
const url = 'https://www.youtube.com/watch?v='+posts.id.videoId,
imgUrl = posts.snippet.thumbnails.default.url,
title = posts.snippet.title,
channelTitle = posts.snippet.channelTitle,
channelUrl = 'https://www.youtube.com/channel/'+posts.snippet.channelId;
return (<div className="col-sm-4 col-lg-4 col-md-4">
<div className="well well-sm media">
<a className="thumbnail pull-left" target="_block" href={url}><img alt={title} src={imgUrl} width="120" height="90" /></a>
<div className="media-body">
<a target="_block" href={url}>{title}</a>
<p>By <a target="_block" href={channelUrl}><span className="label label-info">{channelTitle}</span></a></p>
</div>
</div>
</div>);
};
};
Open the “YouTubeGetData.js” from “src/services” folder and copy past the below code.
export function youtubeApiServiceCall(filterText, pageToken){
let pageTokenVal = '';
if (pageToken) {
pageTokenVal = "&pageToken="+pageToken;
}
const val = filterText;
const url = "https://www.googleapis.com/youtube/v3/search?key=YOUTUBE_API_KEY&q="+val+"&type=video&part=snippet&maxResults=12"+pageTokenVal;
return new Promise((resolve, reject) => {
fetch(url, {
method: 'get',
headers: {
'Accept': 'application/json'
}
}).then(function(res) {
return res.json();
}).then(function (data) {
const posts = data.items.map(obj => obj);
const{nextPageToken,prevPageToken} = data;
const objects = {
'posts':posts,
'nextPageToken':nextPageToken,
'prevPageToken':prevPageToken
};
resolve(objects);
});
});
};
Note: Replace “YOUTUBE_API_KEY” with your youtube API key
Alright… Every thing is done!!!
Now, Time to run the code and see the output
Open the terminal and cd to the project folder like below video
// To run the project
npm start
// To take a build
npm run build
Leave a Reply