First of all, I’m new at Angular. I’m developing an application that integrates AngularJS as frontend and Yii2 as backend. So far everything was doing fine but in the last few weeks I was dealing with an Angular Material headache. I’ve been searching a lot but I couldn’t find the solution.
I’m trying to code a Form with around 10 autocomplete material elements. My data is being fetched by API REST in an Angular Service as an observable. In each autocomplete element I can easily display the options but the problem comes when I try to bind/get the id of the object. DisplayWith just gives me the value of id while I was expecting at least the full object so I can return the name and others properties of the object. I the expect [displayWith] to give me back the whole object so I can treat what property I can return to display.
I’ve seen how to do this with an array of objects or a simple array, but I don’t know how to do it using observables from my Rest Api. Also, I don’t know if is really efficient, for example, to manage so many observables in a form.
I’ve read this feature but unlikely didn’t help me. Even I found some solutions, I havent found any for Observables. Maybe I'm facing wrong the whole thing. Thanks in advance and i will really aprecciate i someone could help me.
So far this is my code for only one autocomplete element.
Angular component
import { Component, OnInit } from '@angular/core';
import { FormBuilder,FormGroup, Validators, FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { startWith, debounceTime, switchMap, map, distinctUntilChanged } from 'rxjs/operators';
import { DedicacionI } from '../../../models/dedicacion.interface'
import { DedicacionesService } from 'src/app/services/dedicaciones.service';
export class DocenteAltaComponent implements OnInit {
myForm = new FormGroup()
myControlDedicaciones = new FormControl();
dedicacionesList: Observable<DedicacionI[]>;
filteredOptionsDedicaciones: Observable<DedicacionI[]>;
constructor (
public fb:FormBuilder,
private dedicaciones:DedicacionesService,
)
{
this._getDedicacionesData();
this.filteredOptionsDedicaciones = this.myControlDedicaciones.valueChanges.pipe(
startWith(null),
debounceTime(200),
distinctUntilChanged(),
switchMap(val => {
return this._filterDedicaciones(val || '')
})
)
}
private _getDedicacionesData():void {
this.dedicacionesList = this.dedicaciones.getDedicaciones();
}
private _filterDedicaciones(val: string) {
return this.dedicacionesList.pipe(
map(response => response.filter(option => {
let aux = option.denominacion.toString();
return aux.toLowerCase().indexOf(val.toString().toLowerCase()) === 0
}))
)
}
public displayDedicacion (dedicacionSel): string {
if (dedicacionSel != null){
return dedicacionSel.denominacion + " (" + dedicacionSel.codigo + ")";
}else{
return "";
}
}
}
Angular html
<form [formGroup]="myForm" (ngSubmit)="save(myForm.value)">
<!-- Dedicaciones -->
<p>
<mat-form-field class="example-full-width">
<input type="text"
placeholder="Dedicación"
aria-label="Number"
matInput
[formControl]="myControlDedicaciones"
[matAutocomplete]="autoDededicacion">
<mat-autocomplete autoActiveFirstOption #autoDededicacion="matAutocomplete" [displayWith]="displayDedicacion">
<mat-option *ngFor="let option of filteredOptionsDedicaciones | async" [value]="option">
<p>{{option.denominacion}} ({{option.codigo}}) </p>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</p>
<!-- /.Dedicaciones -->
</form>
Angular service
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DedicacionI } from '../models/dedicacion.interface';
@Injectable()
export class DedicacionesService {
constructor(private http:HttpClient) { }
getDedicaciones() {
return this.http.get<DedicacionI[]>("http://localhost/yii2-tests/rest/web/index.php/v1/dedicaciones")
}
}