Home > other >  Angular. Just the last value of the array apperas in html table itteration
Angular. Just the last value of the array apperas in html table itteration

Time:09-01

I passed input datas from "create" component via service to the "check" component. I store these input datas in an array('receipts[]') in the "check" component. When ngFor itterate them in a table of the check html file ,there shows JUST the last value of my array. I logged my array to the console and all my datas are in... What can be the proble? Please could you give me an advice? (My whole project: https://github.com/suvegesrebeka/szamlakezelo) Thanks! stackblitz: https://stackblitz.com/edit/angular-ivy-hwald4?file=src/app/app.component.ts,src/app/receiptdata.service.ts,src/app/components/create/create.component.ts,src/app/components/create/create.component.html

the check ts file:

  ngOnInit(): void {
    console.log("check oninit");

    this.subscription();
  }

  receipts:any[]=[];
  subscription(){
    this.receiptdataService.behaveiorSubject$.subscribe((res:any)=>{
      for (const [key, val] of Object.entries(res)) {
        console.log(`${key}: ${val}   2. respo`);
      }
      this.receipts.push(res)
      console.log(this.receipts)
    })
  } 

the check html file:

<h2 >Kiállított számlák:</h2>
<table >
    <tr>
        <th>ID</th>
        <th>Vásárló neve</th>
        <th>Kiállítás dátuma</th>
        <th>Esedékesség dátuma</th>
        <th>Tétel neve</th>
        <th>Komment</th>
        <th>Ár</th>
   <tr>
    <tr *ngFor="let item of receipts" >
        <td>{{item.name}}</td>
        <td >{{item.date}}</td>
        <td >{{item.date2}}</td>
        <td >{{item.item}}</td>
        <td >{{item.comment}}</td>
        <td >{{item.price}}</td>
    </tr>
  
</table>

service:


  private sourceBehav = new BehaviorSubject<any>(null);
  public behaveiorSubject$ = this.sourceBehav.asObservable();
  
  showReceipt(value: any) {
    this.sourceBehav.next(value)
  }

the create component ts :(datas go from here)

  sendData(value: any): void {
    // for (const [key, val] of Object.entries(value)) {
    //   console.log(`${key}: ${val}`);
    // }
    this.receiptdataService.showReceipt(value);
  }

create's html:

<div>
  <h2 >Állítson elő számlát:</h2>
  <form [formGroup]="receiptform" #save="ngForm" (ngSubmit)="onSubmit(save.value)" action="POST">
    <ul>
      <li>
        <label for="cusName" >Vásárló neve</label>
        <input formControlName="name" type="text"  id="cusName" #nameval>
      </li>
      <span *ngIf=" name!.invalid && (name!.dirty || name!.touched)">
        <span [ngStyle]="{'color':'red'}" *ngIf="name!.errors?.['required']">
          A név kötelező!
        </span>
        <span [ngStyle]="{'color':'red'}" *ngIf="name!.errors?.['pattern']">
          Hibás formmátum!
        </span>
      </span>
      <li>
        <label for="date" >Kiállítás dátuma</label>
        <input formControlName="date" [max]="maxDate" type="date"  id="date">
      </li>
      <span *ngIf=" date!.invalid && (date!.dirty || date!.touched)">
        <span [ngStyle]="{'color':'red'}" *ngIf="date!.errors?.['required']">
          A dátum kötelező!
        </span>
      </span>
      <li>
        <label for="date" >Esedékesség dátuma</label>
        <input formControlName="date2" type="date"  id="date">
      </li>
      <span *ngIf=" date2!.invalid && (date2!.dirty || date2!.touched)">
        <span [ngStyle]="{'color':'red'}" *ngIf="date2!.errors?.['required']">
          A dátum kötelező!
        </span>
      </span>
      <li>
        <label for="item" >Tétel neve</label>
        <input formControlName="item" type="text"  id="item">
      </li>
      <span *ngIf=" item!.invalid && (item!.dirty || item!.touched)">
        <span [ngStyle]="{'color':'red'}" *ngIf="item!.errors?.['required']">
          A tétel kötelező!
        </span>
      </span>
      <li>
        <label for="comment">Komment</label>
        <textarea formControlName="comment"  id="comment"></textarea>
      </li>
      <span *ngIf=" comment!.invalid && (comment!.dirty || comment!.touched)">
        <span [ngStyle]="{'color':'red'}" *ngIf="comment!.errors?.['required']">
          Kötelező kommentelni!
        </span>
      </span>
      <li>
        <label for="price">Ár</label>
        <span style="width:30%" >
          <input formControlName="price" type="number" min=1  id="price">
          <span >,-Ft</span>
        </span>
      </li>
      <span *ngIf=" price!.invalid && (price!.dirty || price!.touched)">
        <span [ngStyle]="{'color':'red'}" *ngIf="price!.errors?.['required']">
          Az árkötelező!
        </span>

      </span>
      <button (click)="sendData(save.value)" [disabled]="!receiptform.valid" type="submit"
        >Mentés</button>
      <button routerLink="../subscription" >Visszalépés</button>

    </ul>
  </form>
</div>

CodePudding user response:

The root cause of all you issues is the below line of code

@Component({
  selector: 'app-create',
  templateUrl: './create.component.html',
  styleUrls: ['./create.component.css'],
  providers: [], // <- problem here
})

export class CreateComponent implements OnInit {

never add providers in the component, if you intend to share the service with adjacent components, either let it have providedIn or add to providers of app module.

Another mistake is in the HTML you are not creating table cells for each of the rows, the html table should be restructured as follows!

<h2 >Kiállított számlák:</h2>
<table >
  <tr>
    <th>ID</th>
    <th>Vásárló neve</th>
    <th>Kiállítás dátuma</th>
    <th>Esedékesség dátuma</th>
    <th>Tétel neve</th>
    <th>Komment</th>
    <th>Ár</th>
  </tr>

  <tr></tr>
  <tr *ngFor="let item of receiptObservable$ | async"> <!-- mistake here -->
    <td>{{ item.cusName }}</td>
    <td>{{ item.buyDate }}</td>
    <td>{{ item.realDate }}</td>
    <td>{{ item.product }}</td>
    <td>{{ item.cusComment }}</td>
    <td>{{ item.prodPrice }}</td>
    <td>{{ item.prodPrice }}</td>
  </tr>
</table>
<button routerLink="../create" >
  Új számla kiállítása
</button>

I am intializing a behaviour subject which stores the array and updates if a new row is pushed! and on the other component I subscribe for changes also I am using async pipe which eliminates the need for subscribing to get the array data, another advantage is that it auto unsubscribes from the observable!

I have done a lot of rework and it basically works, do try to tweak it, let me know if any doubts!

forked stackblitz

  • Related