VueJS - невозможно прочитать свойство undefined - PullRequest
0 голосов
/ 09 мая 2020

Я пытаюсь загрузить видео Youtube через их API, и чтобы узнать продолжительность, мне нужно отправить второй запрос API. Проблема, с которой я сталкиваюсь, заключается в том, что иногда этот код работает, иногда он выдает

Error in render: "TypeError: Cannot read property 'contentDetails' of undefined"

Я думаю, это потому, что, когда Vue пытается получить доступ к свойству, его там нет. Если я обращаюсь к переменной (resolvedVideoData) с помощью инструмента Vue Developer при неудачной загрузке, он разрешает только ОДНО видео.

Что я делаю не так? Я вызываю запрос API в created (), поэтому модель DOM еще не загружена?


<script>
import axios from 'axios';
import moment from 'moment'

export default {
    name: 'BlogGrid',
    data(){
        return {
          videos:[],
          base_url_youtube: 'http://www.youtube.com/watch?v=',
          videoId: [],
          resolvedVideoData: [],    
        }
    },
    watch: {
        videos: function (){
           var arrayLength = this.videos.length;
            for (var i = 0; i < arrayLength; i++) {
              this.videoId.push(this.videos[i].id.videoId); 
            }
            this.getVideoDuration()
      }
  },
    created() {
      axios.get(`https://www.googleapis.com/youtube/v3/search?key={{YOUTUBE_API_KEY}}&channelId={{ChannelID}}A&order=date&part=snippet%20&type=video,id&maxResults=50`)
        .then(response => {
          this.videos = response.data.items
  })
  .catch(e => {
    this.errors.push(e)
  })
},
  methods: {
       getVideoDuration(){
        axios.get('https://www.googleapis.com/youtube/v3/videos?id=' + this.videoId.join(', ') + '&part=contentDetails&key={{YOUTUBE_API_KEY}}')
        .then(response => {
          this.resolvedVideoData = response.data.items
  })
  .catch(e => {
    this.errors.push(e)
  })
 }
 }
}
</script>

После дополнительной проверки, если я спамлю сгенерированный URL-адрес для Google API, иногда кажется, что это возвращает одно значение, иногда он возвращает все значения.

Так как было запрошено

 <section class="blog-area ptb-80">
      <div class="container">
        <div class="row">
          <div
            v-for="(item, index) in videos"
            :key="item.etag"
            class="col-lg-4 col-md-6"
          >
            <div class="single-blog-post">
              <div
                class="blog-image"
                :href="base_url_youtube + item.id.videoId "
              >
                <a :href="base_url_youtube + item.id.videoId ">
                  <img
                    :src="item.snippet.thumbnails.high.url"
                    name="videoicon"
                    alt="image"
                  ></a>
                <a :href="base_url_youtube + item.id.videoId ">
                  <div class="overlay hidden-sm">
                    <div class="text">
                      {{ parseDuration(resolvedVideoData[index].contentDetails.duration) }}
                      <br>
                      <a :href="base_url_youtube + item.id.videoId"> <feather type="monitor" /></a>
                    </div>
                  </div>

                </a>
                <div class="date">
                  <feather type="calendar" />
                  {{ format_date(item.snippet.publishedAt ) }}
                </div>
                <div class="blog-post-content">
                  {{ item.snippet.title }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

с другими моими методами.

format_date(value){
          if (value) {
            return moment(String(value)).format('DD-MM-YYYY')
           }
       },
parseDuration(e){
    var n = e.replace(/D|H|M/g,":").replace(/P|T|S/g,"").split(":");

    if(1 == n.length)
        2!=n[0].length && (n[0]="0"+n[0]),n[0]="0:"+n[0];
    else 
        for(var r=1, l=n.length-1; l>=r;r++)
            2!=n[r].length && (n[r]="0"+n[r]);

    return n.join(":")
},

...