2

I'm using Ionic 2, which sits on top of Angular 2. I need to create an array of items. I don't know how many items are going to be in that array.

Here is my Typescript, simplified:

import { Component } from '@angular/core';

import { VgAPI } from 'videogular2/core';

@Component({
  selector: 'page-class',
  templateUrl: 'class.html'
})
export class ClassPage {
  api: any[];

  constructor(...){}

  // Load API when videos are ready
  onPlayerReady(api: VgAPI, i: any) {
    this.api[i] = api;
  }

}

onPlayerReady is called when video players in my view intialize. i is the ID of that player (0, 1, 2, ...).

I'd expect this to construct an array of:

this.api[0] = VgAPI (of player 1)
this.api[1] = VgAPI (of player 2)
this.api[2] = VgAPI (of player 3)
this.api[3] = VgAPI (of player 4)
this.api[4] = VgAPI (of player 5)

Unfortunately, I get the following:

Runtime Error
Cannot set property '1' of undefined

I believe this is because this.api[0] isn't explicitly defined anywhere. But that's a problem, as I don't know how many items where will be. How can I properly define this array to allow this behaviour?

2
  • You need to set your variable as an empty array in constructor: this.api = []; Commented Jul 25, 2017 at 11:45
  • Arrays don't have "keys", they have "indices". All arrays are dynamic, by definition. Commented Jul 25, 2017 at 12:46

2 Answers 2

1

Arrays in JavaScript are naturally dynamic in length so you don't need to provide a size during initialization.

Neither the length of a JavaScript array nor the types of its elements are fixed.

You haven't initialized the array, so you just need to do that, with no size.

i.e.

api: any[]; should be api: any[] = [];

Here's a working JSFiddle with a little clean up.

interface VgAPI {
  name: string;
}

class ClassPage {
  private api: VgAPI[] = [];

  public onPlayerReady = (api: VgAPI, index: number) => {
    this.api[index] = api;
  };
}

let classPage = new ClassPage();
classPage.onPlayerReady({ name: "foo" }, 1);
Sign up to request clarification or add additional context in comments.

Comments

0

It's because api is undefined, you have to set it as an empty array:

@Component({
  selector: 'page-class',
  templateUrl: 'class.html'
})
export class ClassPage {
  // initialize as empty array
  public api: VgAPI[] = [];

  constructor(...){}

  // Load API when videos are ready
  onPlayerReady(api: VgAPI, i: number) {
    this.api[i] = api;
  }
}

5 Comments

I would like to know why someone have down voted this answer. Can't see anything wrong with it.
Probably because the OP's problem amounts to a typo. He got an error saying cannot set property '1' of undefined. Therefore, it is obvious that this.api is undefined. It is not surprising that this.api is undefined, since it was never initialized.
Not very constructive @torazaburo. api is defined in the constructor - I'm aware that api[1] isn't defined (I stated that in my question), and I know that's why I'm getting the error, the question is why that is the case when it's set to any in the constructor. This answer answers that. Your comment is extremely unhelp, unconstructive and wrong; there was no typo, I just wasn't aware I had to initialize as an array.
@mikemike Umm, it doesn't seem that complicated to realize that if you don't initialize something, then it's not initialized. "Define" is not "initialize". Specifying a type does not initialize.
Error says undefined. I am defining it. After asking it seems I need to initialize too. I'm not sure what your problem with all of this is...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.