Array of Objects

Hello everyone :slight_smile:
I can’t find the solution to my problem. I have class Device then I have DeviceService for communication. Finally on page Scenes I need to create array of Device but ends with errors. I have tried nearly everything.
Errors like: Cannot read property ‘undefined’ of undefined;
Cannot read property ‘id’ of undefined
Thank you for help :slight_smile:

Device.ts

export class Device {
id: number;
name: string;
number: string;
constructor() { }
get deviceId(): number {return this.id; }
get deviceNumber(): string {return this.number; }
get deviceName(): string {return this.name; }
set deviceNumber(number: string) {this.number = number; }
set deviceName(name: string) {this.name = name;}
}

Then I made DeviceService which I’ve added to providers

DeviceService.ts

import {Injectable} from '@angular/core';
import {Device} from '../providers/device';
@Injectable()
export class DeviceService {
  deviceCount: number;
  devices: Array<Device>;
  constructor(){}
  getDevices(): Array<Device> {
    return this.devices;
  }
  pushDevice(name, number) {
    number.toString();
    this.devices[this.deviceCount].id++;
    this.devices[this.deviceCount].deviceName = name;
    this.devices[this.deviceCount].deviceNumber = number;
    this.deviceCount++;
  }
}

Scene.ts

import {Component} from '@angular/core';
import {NavController, NavParams, PopoverController, ModalController} from 'ionic-angular';
import {CreateDevicePage} from '../create-device/create-device';
import {PopoverPage} from '../../providers/popover';
import {DeviceService} from '../../providers/device-service';

@Component({
  selector: 'page-scenes',
  templateUrl: 'scenes.html',
})
export class ScenesPage {
  constructor(public navCtrl: NavController,
              public navParams: NavParams,
              public modalCtrl: ModalController,
              public popoverCtrl: PopoverController,
              public deviceCtrl: DeviceService,
  ) { }
  ionViewDidLoad() { }
  launchSecondPage() {
    let modal = this.modalCtrl.create(CreateDevicePage);
    modal.onDidDismiss((data) => {
      this.deviceCtrl.pushDevice(data.name, data.number);
    });
    modal.present();
  }
}
@Component({
    template: `<p>Hey!</p>`,
    providers: [MyService]
})

You have to add your providerto the component.

You mean to the component scene?

still not working Cannot set property ‘deviceId’ of undefined

In every page you want to use the service.

Yes they are properly added. With the same result.

Maybe you have to initialize the devices property of your DevicesSevice class with an empty array:

devices: Array<Device> = [];

so that it is not undefined when you try to add another element to it.

1 Like

First, I noticed some bad advice I want to make sure you don’t follow. Absolutely do not provide your service in every component you want it used in. Provide it in the highest level component you want it shared from. So if you use it in every page, provide it in the app component. If you only use it in a single page it’s fine to provide it in that one.

Secondly, this code is all over the place. You never actually create a new device. It’s also strange that you seem to reference id directly instead of the getter deviceId. When you push a device in the service, you should be creating a new Device, setting the name, number, and id, and then pushing that device onto the array. You could also change the Device constructor to take an id, name, and number so you can just initialize the device all in one line. Then push it to the array.

Also just get rid of deviceCount in the deviceService, it’s redundant. You can just use the length of the array to see what the device count is.

2 Likes

Thank you for great reply :slight_smile:
I have managed to make it work :raised_hands:

1 Like

It is hard to find this kind of informaiton in the Docs.
Is it the same line of code in the app component as in the page?

It is the same line yes, but location matters because Angular has hierarchical dependency injection, and every time you provide a service a new one is constructed. It’s generally expected that services are singletons, and in this case it is definitely expected. This service maintains a list of devices, and that same list needs to be shared among multiple pages. If you provide the service in each component a new copy of the service will be created in each component, so each page would have it’s own list of devices, which wouldn’t provide the expected result.

It’s definitely in the docs. It’s a big part of Angular. The singleton part is here: https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#singleton-services

But that’s part of a much larger page all about dependency injection: https://angular.io/docs/ts/latest/guide/dependency-injection.html

And the style guide talks about services as singletons and where to provide them from: https://angular.io/docs/ts/latest/guide/style-guide.html#!#services

2 Likes

Thank’s for sharing you knowledge it is realy helpful.

Actually I still fight with the ionic docs, but I think it is time to start with the angular docs.

:wink:

Yes, you should definitely start with the Angular docs. Ionic sits on top of Angular, if you don’t know Angular…you won’t really be able to use Ionic, at least not very well :slight_smile:

1 Like