OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Angular Input value doesn't change

  • Thread starter Thread starter A. Vreeswijk
  • Start date Start date
A

A. Vreeswijk

Guest
I have a problem. In my Angular project I have 2 components with an two-way bound parameter. The parameter is an object id. Both components use the same service which stores the list with objects. The parent contains the list where you can select the object and the child shows the selected object details. Here is the code of the parent:

Code:
<div>
  <table>
    <tr>
      <th scope="col">Title</th>
    </tr>
    <tr *ngFor="let offer of service1.findAll();"
        [style.background-color]="offer.rowClicked ? '#ed9b82' : ''"
        (click)="highlightClickedRow(offer)">
      <td>{{offer.title}}</td>
    </tr>
  </table>
</div>

<div>
  <app-detail3 [editedOfferId]="offerSelectedId" (editedOfferChanged)="offerSelectedId=$event"></app-detail3>
</div>

with the typescript:

Code:
@Component({
  selector: 'app-overview3',
  templateUrl: './overview3.component.html',
  styleUrls: ['./overview3.component.css']
})
export class Overview3Component implements OnInit {

  public offerSelectedId: number = -1;

  constructor(public service1: OffersService) { }

  ngOnInit(): void {
  }

  public highlightClickedRow(offer :Offer) {
    let offers: Offer[] = this.service1.findAll();
    for (let i = 0; i < offers.length; i++) {
      if (offers[i] != offer) {
        offers[i].rowClicked = false;
      }
      else {
        offers[i].rowClicked = true;
        this.offerSelectedId = offers[i].id;
      }
    }
  }

}

And here is the detail component:

Code:
<div id="content" *ngIf="editedOfferId != -1">
  <div id="data-table">
    <table>
      <tr>
        <th scope="row" colspan="2">Selected offer details(id = {{service.findById(editedOfferId)!.id}})</th>
      </tr>
      <tr>
        <th scope="row">Title:</th>
        <td><input type="text" id="txtTitle" (input)="checkObjectChanged()"></td>
      </tr>
      <tr>
        <th scope="row">Description:</th>
        <td><input type="text" id="txtDescription" (input)="checkObjectChanged()" value="{{service.findById(editedOfferId)!.description}}"></td>
      </tr>
      <tr>
        <th scope="row">Status:</th>
        <td>
          <select (input)="checkObjectChanged()" id="txtStatus">
            <option *ngFor="let key of keys" [ngValue]="key" [value]="status[key]" [label]="status[key]" [selected]="service.findById(editedOfferId)!.auctionStatus === key"></option>
          </select>

        </td>
      </tr>
      <tr>
        <th scope="row">Highest Bid:</th>
        <td><input id="txtHighestBid" (input)="checkObjectChanged()" value="{{service.findById(editedOfferId)!.valueHighestBid}}"></td>
      </tr>
    </table>
  </div>
</div>
<div *ngIf="editedOfferId == -1">
  <label  id="lblNothingSelected">Nothing has been selected yet</label>
</div>

With the typescript:

Code:
@Component({
  selector: 'app-detail3',
  templateUrl: './detail3.component.html',
  styleUrls: ['./detail3.component.css']
})
export class Detail3Component implements OnInit {

  @Input() editedOfferId: number = -1;
  @Output() editedOfferChanged = new EventEmitter<number>();

  public selectedOffer: Offer = new Offer("", "", new Date(), AuctionStatus.NEW, 0);

  status = AuctionStatus
  keys: Array<number>;

  constructor(public service: OffersService) {
    this.keys = Object.keys(this.status).filter(k => !isNaN(Number(k))).map(Number);
    this.selectedOffer = service.findById(this.editedOfferId)!;
  }

  ngOnInit(): void {
  }

}

Now when I click on an object in the parent component, the details will be loaded in de detail component, but when I edit for example the title input field and then change the object in the parent, I would expect that the data of the new selected object will be loaded. This happens, but only the fields that were not edited at that moment, so when I edit the title, everything will be loaded correctly, but the value of the title will remain the same. Even tough the object has a different title, the value that I was typing stays in the input field. Why is this happening and how can I fix this?
<p>I have a problem. In my Angular project I have 2 components with an two-way bound parameter. The parameter is an object id. Both components use the same service which stores the list with objects. The parent contains the list where you can select the object and the child shows the selected object details. Here is the code of the parent:</p>
<pre><code><div>
<table>
<tr>
<th scope="col">Title</th>
</tr>
<tr *ngFor="let offer of service1.findAll();"
[style.background-color]="offer.rowClicked ? '#ed9b82' : ''"
(click)="highlightClickedRow(offer)">
<td>{{offer.title}}</td>
</tr>
</table>
</div>

<div>
<app-detail3 [editedOfferId]="offerSelectedId" (editedOfferChanged)="offerSelectedId=$event"></app-detail3>
</div>
</code></pre>
<p>with the typescript:</p>
<pre><code>@Component({
selector: 'app-overview3',
templateUrl: './overview3.component.html',
styleUrls: ['./overview3.component.css']
})
export class Overview3Component implements OnInit {

public offerSelectedId: number = -1;

constructor(public service1: OffersService) { }

ngOnInit(): void {
}

public highlightClickedRow(offer :Offer) {
let offers: Offer[] = this.service1.findAll();
for (let i = 0; i < offers.length; i++) {
if (offers != offer) {
offers.rowClicked = false;
}
else {
offers.rowClicked = true;
this.offerSelectedId = offers.id;
}
}
}

}
</code></pre>
<p>And here is the detail component:</p>
<pre><code><div id="content" *ngIf="editedOfferId != -1">
<div id="data-table">
<table>
<tr>
<th scope="row" colspan="2">Selected offer details(id = {{service.findById(editedOfferId)!.id}})</th>
</tr>
<tr>
<th scope="row">Title:</th>
<td><input type="text" id="txtTitle" (input)="checkObjectChanged()"></td>
</tr>
<tr>
<th scope="row">Description:</th>
<td><input type="text" id="txtDescription" (input)="checkObjectChanged()" value="{{service.findById(editedOfferId)!.description}}"></td>
</tr>
<tr>
<th scope="row">Status:</th>
<td>
<select (input)="checkObjectChanged()" id="txtStatus">
<option *ngFor="let key of keys" [ngValue]="key" [value]="status[key]" [label]="status[key]" [selected]="service.findById(editedOfferId)!.auctionStatus === key"></option>
</select>

</td>
</tr>
<tr>
<th scope="row">Highest Bid:</th>
<td><input id="txtHighestBid" (input)="checkObjectChanged()" value="{{service.findById(editedOfferId)!.valueHighestBid}}"></td>
</tr>
</table>
</div>
</div>
<div *ngIf="editedOfferId == -1">
<label id="lblNothingSelected">Nothing has been selected yet</label>
</div>
</code></pre>
<p>With the typescript:</p>
<pre><code>@Component({
selector: 'app-detail3',
templateUrl: './detail3.component.html',
styleUrls: ['./detail3.component.css']
})
export class Detail3Component implements OnInit {

@Input() editedOfferId: number = -1;
@Output() editedOfferChanged = new EventEmitter<number>();

public selectedOffer: Offer = new Offer("", "", new Date(), AuctionStatus.NEW, 0);

status = AuctionStatus
keys: Array<number>;

constructor(public service: OffersService) {
this.keys = Object.keys(this.status).filter(k => !isNaN(Number(k))).map(Number);
this.selectedOffer = service.findById(this.editedOfferId)!;
}

ngOnInit(): void {
}

}
</code></pre>
<p>Now when I click on an object in the parent component, the details will be loaded in de detail component, but when I edit for example the title input field and then change the object in the parent, I would expect that the data of the new selected object will be loaded. This happens, but only the fields that were not edited at that moment, so when I edit the title, everything will be loaded correctly, but the value of the title will remain the same. Even tough the object has a different title, the value that I was typing stays in the input field. Why is this happening and how can I fix this?</p>
Continue reading...
 

Latest posts

Top