Levy4u
Levy4u

Reputation: 91

Dynamically set ion-input value within form using ngFor

I have clicked on probably every single link that came up regarding the "similar questions" and I don't understand what's going on here. I think something in my setup is wrong and other answers aren't working for me.

I have a page displaying a list of leads via *ngFor and I wanted to change it to be editable/updatable so I turned it into a reactive form but the "value" properties aren't showing anything. If i take the item out of the ion-input component, it shows the correct value as plain html but it's not the input value.

For example, in the ion-card-title, this shows "John Doe" : {{item.payload.doc.data().name}} . But in the "value" property of ion-input formControlName="eName" , that same thing is blank.

I'm subscribing to the firestore collection as multiple people use the page and I need the real-time updates when new leads are added or existing ones are changed.

I've tried [(ngModel)] bind but it made every single list item have the same set of data no matter what I did (unless i changed the index eg, item.payload.doc.data().name changed to, items[3].payload.doc.data().name etc.)

The list items are generating correctly and when it wasn't a form it was displaying the correct data for each item. I just can't figure out how to get those item values to already be the set form values when the lead is opened. The idea is you can just change the form entries, click save, and it's updated.

So to recap, i'm trying to get "John Doe" (and the proper subsequent names) to show as the form value using this line : ion-input formControlName="eName" type="text" value="item.payload.doc.data().name"

Here are the relevant portions of code:

.html

<ion-card *ngFor="let item of items; let i = index;">
<ion-card-header>
  <ion-card-subtitle>{{item.payload.doc.data().created.seconds * 1000 | date:'MM/dd/yy' }} </ion-card-subtitle>
  <ion-row>
    <ion-col>
      <ion-card-title>{{item.payload.doc.data().name}} | {{item.payload.doc.data().dates}} </ion-card-title>
    </ion-col>
    <ion-col size="1" class="ion-text-right">
      <ion-button fill="outline" (click)="expandItem(item)">View</ion-button>
    </ion-col>
  </ion-row>
</ion-card-header>

<ion-card-content>
  <app-expandable expandHeight="300px" [expanded]="item.expanded">

      <form [formGroup]="existingLeadForm" class="existingLeadForm" (ngSubmit)="doUpdateLead(item.payload.doc.id)">
        <ion-grid>
      <ion-row>
        <ion-col size="6" size-sm>
          <ion-item>
          <ion-label position="stacked">Name</ion-label>
          <ion-input formControlName="eName" type="text" value="item.payload.doc.data().name"></ion-input>
        </ion-item>
        </ion-col>
        <ion-col size="6" size-sm>
          <ion-item>
          <ion-label position="stacked">Email</ion-label>
          <ion-input formControlName="eEmail" type="email" value="item.payload.doc.data().email"></ion-input>
        </ion-item>
        </ion-col>
        <ion-col size="6" size-sm>
          <ion-item>
          <ion-label position="stacked">Phone</ion-label>
          <ion-input formControlName="ePhoneNumber" type="tel" value="item.payload.doc.data().phoneNumber"></ion-input>
        </ion-item>
        </ion-col>
      </ion-row>
      <ion-row>
        <ion-col size="12" class="ion-text-right">
          <ion-button color="primary-gradient" type="submit">
            <ion-icon name="save"></ion-icon>
            Update
          </ion-button>
          <ion-button color="dark" (click)="archiveLead(item)">
            <ion-icon name="albums"></ion-icon>
            Archive
          </ion-button>
        </ion-col>
      </ion-row>
    </ion-grid>
    </form>

  </app-expandable>
</ion-card-content>

.ts

existingLeadForm:FormGroup;
items: any = [];    
subscription$: Subscription;

  this.existingLeadForm = this.formBuilder.group({
    eEmail: ['', Validators.compose([Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$'), Validators.required])],
    eName: ['', Validators.required],
    ePhoneNumber: ['', Validators.required],
  })

            this.subscription$ = this.firestore.collection('leads', ref => ref.where('archived','==',false).orderBy('created','asc'))
        .snapshotChanges().subscribe(data => {
          this.items = data
          this.items.expanded = false
          console.log(data)
        });

The "console.log(this.data)" shows:

(5) [{…}, {…}, {…}, {…}, {…}, expanded: false]
0: {type: "added", payload: {…}, expanded: false}
1: {type: "added", payload: {…}, expanded: false}
2: {type: "added", payload: {…}, expanded: false}
3: {type: "added", payload: {…}, expanded: false}
4: {type: "added", payload: {…}, expanded: false}
expanded: false
length: 5
__proto__: Array(0)

What am I missing? Please point me in the right direction. Thank You

Upvotes: 0

Views: 2638

Answers (1)

f.overflow
f.overflow

Reputation: 298


maybe I am missing it, but I can not find the ngFor in your template.

One way could be to set the value manually in your subscribe part.
Something like:

this.existingLeadForm.controls['email'].setValue(emailFromData)

What I prefer when it comes to subscriptions is StateManagement.
In this case Ngxs with its awesome part Ngxs From.

You can bind data directly to your form and in return instantly display changes - both ways.
Maybe do you want to have a closer look

Upvotes: 0

Related Questions