cannot read property global array of undefined in nativescript angular2
Asked Answered
O

3

6

I got a runtime error as cannot read property listArr of undefined. I need to reuse that same array in multiple components. That's why I'm using Global array

I have added relevant code.please check it.

Global.ts :

export class Global {

    public static listArr: ObservableArray<ListItem> = new ObservableArray<ListItem>();

}

ts file:

 Global.listArr.push(data.items.map(item => new ListItem(item.id, item.name, item.marks)));

html file:

<ListView [items]="Global.listArr"  > </ListView>
Oniskey answered 31/8, 2017 at 6:49 Comment(0)
T
4

I would suggest you to go for Shared Services. Keep the global array in the service mark the service as a provider in app.module i:e your main module.

Service

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

@Injectable()
export class Service{

    public static myGloblaList: string[] = [];

    constructor(){}


}

add it to providers array of NgModule.

Now you can use it in any Component like

constructor(private service : Service){
  let globalList = this.service.myGlobalList;// your list
}

The reason i opt for a service is it uses Angular's Dependency Injection and it is the best Angular way to have a global variable and have it shared across Components.

And if you want the component to be auto notified of the changes in the array while push and pop you can make use of Behaviour subject in Services.LINK- question 2

Theola answered 3/9, 2017 at 17:17 Comment(1)
Thanks for this suggestion. this answer worked perfectly. In service class, it seems no need to declare static keyword for global array.I'm able to get the expected result.Oniskey
G
4

You cannot access the class static property directly in your template. You need to create an instance of the property in order to use it.


In this specific case, create an instance in the class referring to Global.listArr. You can use this variable to push data and for using in the template. This will remain up-to-date for other components as well.

Ts file:

// class variable 
globalList: Global.listArr;

// use in some method 
this.globalList.push(data.items.map(item => new ListItem(item.id, item.name, item.marks)));

Html:

<ListView [items]="globalList"> </ListView>

Link to working demo.

Gagliardi answered 31/8, 2017 at 6:57 Comment(4)
I'm getting compile error property listArr doesn't exist on type GlobalOniskey
No I need to use global array directly to templates. Because I'm reusing it in multiple componentsOniskey
You have to create an instance. You cant just use that that way AFAIK. Your list will remain updated you dont have to worry about that.Gagliardi
see this demo: stackblitz.com/edit/angular-dfahyb?file=app%2Fapp.component.tsGagliardi
T
4

I would suggest you to go for Shared Services. Keep the global array in the service mark the service as a provider in app.module i:e your main module.

Service

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

@Injectable()
export class Service{

    public static myGloblaList: string[] = [];

    constructor(){}


}

add it to providers array of NgModule.

Now you can use it in any Component like

constructor(private service : Service){
  let globalList = this.service.myGlobalList;// your list
}

The reason i opt for a service is it uses Angular's Dependency Injection and it is the best Angular way to have a global variable and have it shared across Components.

And if you want the component to be auto notified of the changes in the array while push and pop you can make use of Behaviour subject in Services.LINK- question 2

Theola answered 3/9, 2017 at 17:17 Comment(1)
Thanks for this suggestion. this answer worked perfectly. In service class, it seems no need to declare static keyword for global array.I'm able to get the expected result.Oniskey
S
0

Best I can tell you cannot reference a global variable directly in a template as the template is bound to a component instance. You will have to provide a path through the component to the template to get the global values to render. While creating a service is a great option, you could also create a getter on the component and wrap the global variable.

See a Working Demo

The gist of this is:

export class AppComponent  {
  
  get getListArr() {
      return Global.listArr;
    }
}

export class Global {

    public static listArr: string[] = [ 'a', 'b', 'c' ];

}
<!-- in your template get it this way -->
Gloabl static list with getter: {{getListArr}}
Sholokhov answered 10/9, 2017 at 10:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.