简体   繁体   中英

ERROR TypeError: Cannot read property 'length' of undefined angular 8

I made a site to pick a cat at random like Cat and Mash, but I have an error that I cannot understand.

I have a JSON object in which there are urls that contain images. I need to display the images randomly but not 2 times the same image.

Console:

在此处输入图像描述

Why is length undefined?

import { Component, OnInit } from '@angular/core';
import { CatService } from '../services/cat.service';
import { CatList, Cat } from '../model/cat';

@Component({
  selector: 'app-cat',
  templateUrl: './cat.component.html',
  styleUrls: ['./cat.component.css']
})
export class CatComponent implements OnInit {
    twoCatsArray: Cat[] = [];
    allcats: Cat[];
    constructor(private catService: CatService) {}
    ngOnInit() {
        this.showMeTwoCats();
    }
    showMeTwoCats() {
        this.catService.getCats().subscribe((cats: CatList) = > {
            this.allcats = cats.images;
            this.twoCatsArray = this.chooseTwoRandomCats(this.allcats);
        });
    }
    chooseTwoRandomCats(cats: Cat[]): Cat[] {
        const firstCatIndex = this.getRandomIndex(cats.length);
        const secondCatIndex = this.getRandomIndex(cats.length, firstCatIndex);
        return [cats[firstCatIndex], cats[secondCatIndex]];
    }
    getRandomIndex(maxValue: number, differentThanValue ? : number): number {
        let index: number;
        do {
            index = this.getRandomInt(maxValue);
        } while (index === differentThanValue);
        return index;
    }
    getRandomInt(max): number {
        return Math.floor(Math.random() * Math.floor(max));
    }
    voteForThisCat(id: string) {
        const likedCatindex = this.allcats.findIndex((cat: Cat) = > cat.id === id);
        const newRating = this.getIncrementedCatRatingValue(this.catService.catVote[likedCatindex].rating);
        this.catService.catVote[likedCatindex].rating = newRating;
        this.twoCatsArray = this.chooseTwoRandomCats(this.allcats);
    }
    getIncrementedCatRatingValue(rating: number | undefined): number {
        return rating ? ++rating : 1;
    }
}

Length and index aren't the same thing. Indices are 0 based, length starts at 1. So, An array with 2 items will have a length of 2, but the index of the second item is index 1. You need to subtract 1 from the length. Its selecting an index that doesnt exist.

 var cats = []; cats.push('Felix'); cats.push('Molly'); console.log('L: ' + cats.length); // L: 2 console.log('0: ' + cats[0]); // 0: Felix console.log('1: ' + cats[1]); // 1: Molly console.log('I: ' + cats[cats.length]); // I: Undefined

DO you have any values for this.allCats ?

If Yes

You are getting the error because you are trying to get element from a position that doesn't exist in array.

index in array is a read-only property that is the zero-based index of the match in the string.

Each element in the array has an index , which is just its numerical position in the sequence of elements. If the array is A, then the i-th element of the array is A[i]. The number of elements in an array is called its length. The length of an array A is A.length.

So if you wish to grab the nth element from array A, you need to access A[n-1]

I feel I'm missing some info, but with what I've got, you have the problem in chooseTwoRandomCats, to which you are passing this.allCats, which is undefined.

You do this:

allcats: Cat[];

then you do this:

this.catService.getCats().subscribe((cats: CatList) => {
  this.allcats = cats.images;
  this.twoCatsArray = this.chooseTwoRandomCats(this.allcats);
});

to end up doing this:

const firstCatIndex = this.getRandomIndex(cats.length);
const secondCatIndex = this.getRandomIndex(cats.length, firstCatIndex);

so, is catService.getCats() returning any cats?

Your CatList model has an "images" property? It seems to be an array, so it probably don't have.

If this is the case, you're assigning undefined to "allcats". If not, check the result property images of cats, maybe your service doesn't return anything.

To avoid the error (but not resolve) you can do something like this:

this.allcats = cats.images || [];

[ json

I copied a json I forgot the key images in my json

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM