1

In previous angular version we had $scope.apply to detect changes , So i below code i have data from detailService that is printed now i am pushing data to object its throwing error object property is undefined , what is correct approach in new angular version to push data to array and bind it to the dom ?

app.component.ts

  import { Component, OnInit,Pipe, PipeTransform, EventEmitter, Output } from '@angular/core';
import { DetailService } from '../detail.service';
import { StreamService } from '../stream.service';
import { MatTableDataSource } from '@angular/material';
import {GtConfig} from '@angular-generic-table/core';
import { GenericTableComponent} from '@angular-generic-table/core';
import * as io from 'socket.io-client';


export interface Element {
        ticketNum: number;
        ticketOpened: number;
        eventType: string;
        riskIndex: string;
        riskValue: number;
        severity: string;
        lastModifiedDate: number;
        assetID: string;
    }
    @Component({
      selector: 'app-detail',
      templateUrl: './detail.component.html',
      styleUrls: ['./detail.component.css'],

    })
export class DetailComponent{
  messageArray: any[];
    message1:Object = {};
   public secondConfigObject: GtConfig<any>;

    constructor(private detailService: DetailService) {
        this.secondConfigObject = {
            settings: this.getBaseSettings(),
            fields: this.getBaseFields(),
            data: []
        };
    };

    ngOnInit() {
        this.detailService.currentMessage1.subscribe(message1 => {
            console.log('eventINDetailComp',message1);
            this.secondConfigObject.data.push(message1);
        });
    }

}

app.component.html

<div class="table-responsive">
    <generic-table [gtClasses]="'table-hover'" #myCustomTable [gtSettings]="secondConfigObject.settings" [gtFields]="secondConfigObject.fields" [gtData]="secondConfigObject.data"></generic-table>
</div>
hussain
  • 6,587
  • 18
  • 79
  • 152
  • Do you use `ChangeDetectionStrategy.OnPush`? If so, you can try removing that option. Otherwise, you will find a few ways to force change detection in [this answer](https://stackoverflow.com/a/34829089/1009922). – ConnorsFan Jan 19 '18 at 15:24
  • @ConnorsFan changes are automatically detected within angular 2+ – mast3rd3mon Jan 19 '18 at 15:26
  • @mast3rd3mon - Not always, especially with [ChangeDetectionStrategy.OnPush](https://blog.angular-university.io/onpush-change-detection-how-it-works/). – ConnorsFan Jan 19 '18 at 15:28
  • @ConnorsFan unless running something outside the angular scope, it always does, thats the benefits of using angular over angularjs or other frameworks – mast3rd3mon Jan 19 '18 at 15:29
  • @mast3rd3mon - I invite you to take a look at the cases illustrated in [this document](https://blog.angular-university.io/onpush-change-detection-how-it-works/). – ConnorsFan Jan 19 '18 at 15:56
  • i dont have that high level understanding i will really appreciate if you can provide code example as answer, document does not show any example – hussain Jan 19 '18 at 15:59
  • you dont need to follow the document he linked, its not a fix for your issue – mast3rd3mon Jan 19 '18 at 16:00
  • its very simple i have data from service that i want to push it to `secondconfigObject.data` but this.detailSerive is invoking when application launched and it throws error undefined that is abvious because i dont have event at that time, its row clicked event that is passed to service from other component, not sure what is missing in the code – hussain Jan 19 '18 at 16:13
  • @ConnorsFan thats just other ways of writing it, but they arent needed – mast3rd3mon Jan 19 '18 at 16:25
  • @hussain did you try implementing the `@Output()` i mentioned in the chat? – mast3rd3mon Jan 19 '18 at 16:25
  • @mast3rd3mon - Yeah, the question is about avoiding a run-time error, not about change detection. Maybe the title should be changed. – ConnorsFan Jan 19 '18 at 16:31
  • @Output() onClick = new EventEmitter(); added this after component getting error `error TS1146: Declaration expected.` – hussain Jan 19 '18 at 16:33
  • `this.secondConfigObject.data.push(Object.assign({},message1))` this resolved the issue thank you all for the help – hussain Jan 19 '18 at 17:49

1 Answers1

2

You should move the code from the constructor to the start of the ngOnInit() function so the data gets set once the page has been created, not during.

As for data binding, variables on the screen/html will automatically update when they are changed in the code behind

mast3rd3mon
  • 8,229
  • 2
  • 22
  • 46
  • it throws error at `message1.prop` is undefined if i move code inside `ngOnInit` not sure why this is invoking , this is row click event it should only invoke when we have data pass from detail service – hussain Jan 19 '18 at 15:28
  • where do you use message1.prop? i cant see it in your code? – mast3rd3mon Jan 19 '18 at 15:29
  • i am just giving you example so in subscribe i have message1 that is the object coming from service now properties are undefined on that because this.detailService.currentMessage1 invoked on application launch it should not – hussain Jan 19 '18 at 15:36
  • if you put the subscribe in the ngOnInit, then it should be invoked when the application is launched – mast3rd3mon Jan 19 '18 at 15:38
  • but i am passing the event when row is clicked in the table what will be correct approach in that case, basically passing data object from one table to another – hussain Jan 19 '18 at 15:39
  • you are passing the event straight away when the page loads, not when a row is clicked – mast3rd3mon Jan 19 '18 at 15:40
  • i get event in detail serivce when row is clicked so now how to push event in `secondConfigObject` once i get it from service – hussain Jan 19 '18 at 15:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163500/discussion-between-mast3rd3mon-and-hussain). – mast3rd3mon Jan 19 '18 at 15:42