如何在youtube api上运行搜索查询,收到错误

时间:2017-11-14 00:52:56

标签: reactjs youtube

我正在编写我的第一个React应用程序,而且我遇到了Youtube API的问题。我写了一个单独的Youtube搜索功能,如:

var searchYouTube = (options, callback) => {
  $.get('https://www.googleapis.com/youtube/v3/search', {
    key: window.YOUTUBE_API_KEY,
    q: options.query,
    maxResults: options.max,
  }).done(function(data) {
    console.log(data);
    callback(data);
  });
};

window.searchYouTube = searchYouTube;

每次搜索输入发生变化时都会触发。你可以在我的app.jsx中看到这个组件:

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      videos: exampleVideoData,
      currentVideo: exampleVideoData[0]
    };
  }

  renderSearch(term) {
    console.log($(term.target).val());
    this.setState({
      videos: searchYouTube({query:$(term.target).val(),max:5})
    });
  }

  setVideo(video) {
    this.setState({
      currentVideo: video
    });
  }

  render() {
    return (
      <div>
        <nav className="navbar">
          <div className="col-md-6 offset-md-3">
            <div><Search renderSearch={this.renderSearch.bind(this)}/></div>
          </div>
        </nav>
        <div className="row">
          <div className="col-md-7">
            <div><VideoPlayer currentVideo={this.state.currentVideo}/></div>
          </div>
          <div className="col-md-5">
            <div><VideoList videos={this.state.videos} setVideo={this.setVideo.bind(this)}/></div>
          </div>
        </div>
      </div>
    );
  }
}

// In the ES6 spec, files are "modules" and do not share a top-level scope
// `var` declarations will only exist globally where explicitly defined
window.App = App;

最后,我得到的错误是:

    {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Required parameter: part",
    "locationType": "parameter",
    "location": "part"
   }
  ],
  "code": 400,
  "message": "Required parameter: part"
 }
}

有关我需要重组的任何建议吗?我相信它是searchYoutube函数的结构。也许我错过了一个参数?

1 个答案:

答案 0 :(得分:0)

控制台日志清晰:

"message": "Required parameter: part",

表示您必须在选项中添加part。我建议添加以下内容:

var searchYouTube = (options, callback) => {
  $.get('https://www.googleapis.com/youtube/v3/search', {
    key: window.YOUTUBE_API_KEY,
    q: options.query,
    part: 'snippet', //  this one was missing 
    maxResults: options.max,
  }).done(function(data) {
    console.log(data);
    callback(data);
  });
};

它会起作用。别担心!和演示如下:

const { Component } = React;

class SearchBar extends Component {
  state = { term: '' };

  render() {
    return (
      <div className="search-bar">
        <input
          value={this.state.term}
          onChange={event => this.onInputChange(event.target.value)}
        />
      </div>
    );
  }

  onInputChange = term => {
    this.setState({ term });
    this.props.onSearchTermChange(term);
  };
}

const VideoDetail = ({ video }) => {
  if (!video) {
    return <div>Loading...</div>;
  }

  const videoId = video.id.videoId;
  const url = `https://www.youtube.com/embed/${videoId}`;

  return (
    <div className="video-detail col-md-8">
      <div className="embed-responsive embed-responsive-16by9">
        <iframe className="embed-responsive-item" src={url} />
      </div>
      <div className="details">
        <div>
          {video.snippet.title}
        </div>
        <div>
          {video.snippet.description}
        </div>
      </div>
    </div>
  );
};

const VideoListItem = ({ video, onVideoSelect }) => {
  const imageUrl = video.snippet.thumbnails.default.url;

  return (
    <li onClick={() => onVideoSelect(video)} className="list-group-item">
      <div className="video-list media">
        <div className="media-left">
          <img className="media-object" src={imageUrl} />
        </div>
        <div className="media-body">
          <div className="media-heading">
            {video.snippet.title}
          </div>
        </div>
      </div>
    </li>
  );
};

const VideoList = props => {
  const videoItems = props.videos.map(video => {
    return (
      <VideoListItem
        onVideoSelect={props.onVideoSelect}
        key={video.etag}
        video={video}
      />
    );
  });

  return (
    <ul className="col-md-4 list-group">
      {videoItems}
    </ul>
  );
};

const InvalidApiKey = () => (<h1>Sorry you do not give a valid YOUTUBE API key. Refresh the page or Run the snippet again and give a valid API key. </h1>)


class App extends Component {
  state = {
    videos: [],
    selectedVideo: null,
    error: false
  };
  componentDidMount() {
    this.videoSearch('Sport');
  }

  searchYouTube(options, callback) {
    $.get('https://www.googleapis.com/youtube/v3/search', {
      key: this.props.youtubeApiKey,
      q: options.query,
      part: 'snippet',
      maxResults: options.max
    }).done(function(data) {
      callback(data);
    }).fail(() => this.setState({error: true}))
  }
  videoSearch = (term) => {
    this.searchYouTube({ key: this.props.youtubeApiKey, term: term }, data => {
      this.setState({
        videos: data.items,
        selectedVideo: data.items[1]
      });
    });
  }

  render() {
    // const videoSearch = _.debounce(term => {
    //   this.videoSearch(term);
    // }, 300);
    if (this.state.error) return  <InvalidApiKey />

    return (
      <div>
        <SearchBar onSearchTermChange={this.videoSearch} />
        <VideoDetail video={this.state.selectedVideo} />
        <VideoList
          onVideoSelect={selectedVideo => this.setState({ selectedVideo })}
          videos={this.state.videos}
        />
      </div>
    );
  }
}

const youtubeApiKey = prompt(
  'Give a valid YOUTUBE API KEY and everything should work: '
);


ReactDOM.render(
  youtubeApiKey
    ? <App youtubeApiKey={youtubeApiKey} />
    : <InvalidApiKey />,
  document.querySelector('#app')
);
.search-bar {
  margin: 20px;
  text-align: center;
}

.search-bar input {
  width: 75%;
}

.video-item img {
  max-width: 64px;
}

.video-detail .details {
  margin-top: 10px;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.list-group-item {
  cursor: pointer;
}

.list-group-item:hover {
  background-color: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<div id="app" />