0

I am a noob in angular 5 trying to set multiple variable in result of API call but changes to the variable are not reflecting in view eventhough logging the variable on console displays its value in component(ts file or controller).

In the following code changes to partnerPlanInfo varibale are getting reflected in the view but changes to servData1 variable are not reflecting in the view.

So please guide me where I am missing something which is causing this issue.

    import { Component, OnInit, ViewEncapsulation } from '@angular/core';
    import { MerchantService } from '../merchant.service';
    import {Observable} from 'rxjs/Rx';
    import { HttpClient, HttpParams } from '@angular/common/http';
    import { Plan } from '../models/Plan';
    import {ChangeDetectorRef} from '@angular/core';
    import { ChangeDetectionStrategy } from '@angular/core';

    @Component({
     selector: 'app-dashboard',
     templateUrl: './dashboard.component.html',
     styleUrls: [
    './dashboard.component.scss',
    './merchantAdd.scss',
    './intlTelInput.scss',
    './checkbox.scss',
    './merchant_type.scss',
    './redeemlocation.scss',

    ],
    encapsulation: ViewEncapsulation.None,
    providers:[MerchantService, HttpClient] ,
    changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class DashboardComponent implements OnInit {
    public merchants;
    public partnerPlanInfo;
    public customPlan;
    public planServices: any[]  = new Array();
    public planInfo: any;
    public planService: any;
    public serviceData:any[] = new Array();
    public planInfoArray: any[] = new Array();
    public servData: any;
    public servData1: any[]=  new Array();


    constructor(private _merchantServices: MerchantService,private   
    ref:ChangeDetectorRef) {

     }

  ngOnInit() {

   this.getPartnerPlan();
   //let timer = Observable.timer(2000, 5000);
  // timer.subscribe(() => this.getPartnerPlan());
  }

  getPartnerPlan()
  {
    let partnerPlanRequestData  = new HttpParams().set('partnerId','prtnr000000000000001').set('planType','0');



    this._merchantServices.getPlan(partnerPlanRequestData).subscribe( // the first argument is a function which runs on success
      parnerPlan => { this.partnerPlanInfo = parnerPlan;


       this.servData1= this.generateServiceData(parnerPlan);

        console.log(this.servData1);

        this.ref.detectChanges();
      },
      // the second argument is a function which runs on error
      err => console.error(err),
      // the third argument is a function which runs on completion
      () => console.log('done loading partner plan'+this.partnerPlanInfo)
    );
    //console.log(this.planServices);


  }


  generateServiceData(parnerPlan)
  {
    let count=0;
    for (this.planInfo of parnerPlan){
      var planArray:any[] = new Array();
      planArray[this.planInfo.id] = this.planInfo.planServicesDetail;
      console.log(planArray);
      this.serviceData[count]=planArray;
      count++;
          }
    return this.serviceData;

        }

      }

console.log(this.servData1); displays the result as

[planm000000000000016: [0: {insertMode: false, flags: "0000000000", createdOn: "2018-02-23T07:19:23", updatedOn: "2018-02-23T07:19:23", createdBy: "admin"}]]

but value of servData1 is not getting reflected in view. When I print it like {{ servData1 }} then it is getting displayed as ,,. When I am trying to loop over servData1 in view using

<div *ngFor="let ser of servData1">
  <p>{{ ser }}</p>
</div>

Then it is showing

<!--bindings={
  "ng-reflect-ng-for-of": ",,"
}-->
8
  • is it possible that a HOST component of this component, also has a custom change detection? do you have this.ref.detach() or such on one of the containing components ? Commented Apr 6, 2018 at 6:43
  • @Stavm No I don't have any such component. Commented Apr 6, 2018 at 6:44
  • can you try adding this.ref.reattach() to this component's constructor Commented Apr 6, 2018 at 6:45
  • also what happens if you place a simple string in the html template {{myString}} and in your component you try and change it exactly where you do with the complex array of yours. myString = 'hello' or such, does it change on the DOM ? Commented Apr 6, 2018 at 6:48
  • Yes, When I am hard coding the variable with simple string then that value is shown in the view. Commented Apr 6, 2018 at 6:51

4 Answers 4

1

Troubleshoot the issue

First of all you have to find the structure of the json data by using json pipe

{{myJsonData|json}}

Find solution

After finding the structure you can find the keys to print. In the above issue you can try to print like this :

<div *ngFor="let ser of servData1">
  <div *ngFor="let serDetails of ser">{{serDetails.insertMode }}</div>
</div>
Sign up to request clarification or add additional context in comments.

4 Comments

@Nazeer Thanks for replying, but still getting <!--bindings={ "ng-reflect-ng-for-of": ",," }-->
Whats the result of simple <div>{{servData1| json }}</div> ? can you get the result ?
It displays [ [], [], [] ]
Which means your data does not available in the template. Please remove the unnecessary changeDetection modules from the component and test again or declare a temporary array and display in template.
0

It seems that your datastructure for servData1 is like this

[id:
  [0:{},
   1:{},
   n:{}
  ]
]

which means you have an array with map, and each entry in the map is a new array with a map. You need a double for-loop to print your inner most objects.

Try with

<div *ngFor="let ser of servData1">
  <div *ngFor="let serDetails of ser"></div>
{{serDetails | json}} 
</div>

This will print the object inside the inner most element in your datastructure. Added a json pipe just to make the print pretty. It is probably not needed.

5 Comments

Thanks for replying but still getiing <!--bindings={ "ng-reflect-ng-for-of": ",," }-->
if you use onPush strategy, you are telling angular that there should not be a change detection in this component. Maybe you can remove that attribute from your component as well.
@Stavm I was just trying various suggested methods on stackoverflow. So thats why I added ChangeDetectionStrategy.OnPush but it didn't worked.
removing ChangeDetectionStrategy.OnPush didn't made any difference.
comment went up to the question guys*
0

Try to use pipe like this way but need to configure according to your object property:

@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
  transform(value, args:string[]) : any {
    let keys = [];
    for (let key in value) {
      keys.push({key: key, value: value[key]});
    }
    return keys;
  }
}

and your code is:

<div *ngFor="let ser of servData1 | keys">
  <div *ngFor="let serDetails of ser">{{serDetails.insertMode }}</div>
</div>

or convert your json to key object in componet

Object.keys(servData1);

1 Comment

Thanks, Now am getting <!--bindings={ "ng-reflect-ng-for-of": "[object Object],[object Object" }-->
0

your object values in servData1 is not a valid JSON. enter image description here

and as such it can not be serialized to an array. remove the slashes on the server prior to sending this

1 Comment

its a copy paste issue backlashes are not there actually.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.