0
import React, { Component } from "react";
import Header from "components/Header/Header.jsx";
import Footer from "components/Footer/Footer.jsx";


class Coach extends Component {
  constructor(props){
    super(props)
    this.state = {
      title    : '',
      duration : '',
      url : '',
      video_id : ''
    }
  }

  youtube_api_key = "AIzaSyD8IX7eL0hyIDos4L9tqZ1RyVpqBL6tNuw";

  getVideoTitle(video_id) {
    let title_url = `https://www.googleapis.com/youtube/v3/videos?id=${video_id}&key=${this.youtube_api_key}&fields=items(snippet(title))&part=snippet`
    fetch(title_url)
    .then(response => response.json())
    .then(users => {
     return users['items'][0]['snippet']['title']
    })
  }

  getVideoDuration(video_id) {
    let duration_url = `https://www.googleapis.com/youtube/v3/videos?id=${video_id}&part=contentDetails&key=${this.youtube_api_key}`;
    fetch(duration_url)
    .then(response => response.json())
    .then(users => {
      return users['items'][0]['contentDetails']['duration']
    })
  }


  HandleUrl = (event) => {
    this.setState({url:event.target.value})
  }

  SubmitUrl = () => {

    let url = this.state.url;
    let video_id = ''
    if (url.split('?').length > 1){
      video_id = url.split("?")[1].split("=")[1];
    } else {
      video_id = url;
    }
    let title    = this.getVideoTitle(video_id)
    let duration = this.getVideoDuration(video_id)
    let id = localStorage.getItem("id")

    console.log(this.title, this.duration, id)

    fetch('http://127.0.0.1:8000/video/', {
      method: 'post',
      headers:{'Content-Type': 'application/json'},
      body: JSON.stringify({
        title    : this.state.title,
        duration : this.state.duration, 
        id       : id,
        url      : video_id 
      })
    })
    .then(response => response.json())
    .then(res => {
      console.log(res)
    })
  }


  render() {
    return (
      <div>
        <Header />
        <section>
        <br/>
          <div className="block no-padding">
          <div className="container">
          <div className="row">
            <div class="col-lg-12 column">
              <div class="contact-form">
                <h3>Upload Videos</h3>
                <div style={{ float: 'left', width: '100%', display: 'block' }}>
                  <div class="row">
                    <div class="col-lg-10">
                      <div class="pf-field">
                        <input type="text" placeholder="Video Url" onChange={ this.HandleUrl } />
                      </div>
                    </div>
                    <div class="col-lg-2">
                      <button type="button" onClick={this.SubmitUrl }>Submit</button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <br/>

          <div>
            <table class="table table-hover table-borderless">
              <thead style={{ background:'#fb236a',borderRadius:'5px', color:'#fff' }}>
                <tr>
                  <th style={{ border:'none' }}>Firstname</th>
                  <th style={{ border:'none' }}>Lastname</th>
                  <th style={{ border:'none' }}>Email</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td style={{ border:'none' }}>John</td>
                  <td style={{ border:'none' }}>Doe</td>
                  <td style={{ border:'none' }}>[email protected]</td>
                </tr>
              </tbody>
            </table>
          </div>

          </div>
          </div>
          </section>
        <Footer />
      </div>
    )
  }


}


export default Coach; 

Here i am calling getVideoTitle() and getVideoDuration() function inside SubmitUrl() by passing video_id but i am getting empty data.

but it is showing in the console inside the same function. I tried it by keeping data inside state also.

When i am reding data from state after adding it into state still showing empty.

please have a look into my code.

5
  • You need to bind your functions in the constructor. Commented Mar 12, 2019 at 18:22
  • why not switching getVideoTitle() and getVideoDuration() to arrow function? Commented Mar 12, 2019 at 18:24
  • I tried arrow function also Commented Mar 12, 2019 at 18:27
  • You must understand that this.getVideoTitle(video_id) is an async call, same as any other method that uses the 'fetch' function. Which means getVideoTitle returns a default value which is "undefined" before even fetch is done fetching data from googleapis. Do you know async/await? That's what you need because you have the 'synchronous' mind-set Commented Mar 12, 2019 at 18:30
  • const title = await coach.getVideoTitle(someId) Commented Mar 12, 2019 at 18:35

3 Answers 3

1

It's because fetch returns a promise which needs be awaited or used with .then

You could change your functions to be:

getVideoTitle(video_id) {
  let title_url = `___`
  return fetch(title_url).then(response => response.json());
}

And then in SubmitUrl to:

SubmitUrl = async () => {
  ...
  let title = await this.getVideoTitle(video_id);
Sign up to request clarification or add additional context in comments.

Comments

0

You can use await and async functions instead the promises.

async getVideoTitle(video_id) {
let title_url = `https://www.googleapis.com/youtube/v3/videos?id=${video_id}&key=${this.youtube_api_key}&fields=items(snippet(title))&part=snippet`
const result =  await fetch(title_url)
const users = await result .json()
return users['items'][0]['snippet']['title']

}

let title = await this.getVideoTitle(video_id)

Comments

0

You should make the getVideoTitle() and getVideoDuration() asynchronous since you are fetching data. Use Aysnc/Await to wait for data returned from fetching.

getVideoTitle = async(video_id) => {
    let title_url = `https://www.googleapis.com/youtube/v3/videos?id=${video_id}&key=${this.youtube_api_key}&fields=items(snippet(title))&part=snippet`
    let response = await fetch(title_url)
    let data = await response.json()
    return data;
  }

 getVideoDuration = async(video_id) => {
    let duration_url = `https://www.googleapis.com/youtube/v3/videos?id=${video_id}&part=contentDetails&key=${this.youtube_api_key}`;
    let response = await fetch(duration_url)
    let data = await response.json()
    return data;
  }

In SubmitUrl(),

let videoTitleResult = this.getVideoTitle(video_id)
videoTitleResult.then( result => {
  title = result
})

2 Comments

it returns Promise {<pending>}
The promise will always be pending as long as its results are not resolved yet. You have to call .then on the promise to capture the results. See my edits

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.