Reputation: 173
I need to display the data returned from the FireStore in the screen fields when loaded, but buildForm () is called before the Subscribe, so it does not display the data returned from the FireStore in the fields on the screen.
perfil-model.ts:
export class Perfil {
nome: string;
}
authService.ts:
getPerfil() {
return this.afs.doc<Perfil>(`perfil/${this.id}`)
.snapshotChanges()
.map(p => {
return { ...p.payload.data() };
});
}
perfilUser.component.ts:
perfil: Perfil = new Perfil();
perfilForm: FormGroup;
ngOnInit() {
const subscribe = this.authService
.getPerfil()
.subscribe((p: any) => {
subscribe.unsubscribe();
this.perfil = p;
})
this.buildForm();
}
buildForm() {
this.perfilForm = this.formBuilder.group({
nome: this.perfil.nome,
});
}
perfilUser.component.html:
<form [formGroup]="perfilForm" novalidade>
<div class="row">
<div class="form-group col-12 col-sm-12 col-md-7 col-lg-4 col-xl-4">
<label for="name">Nome*</label>
<input type="text" class="form-control" formControlName="nome" placeholder="Nome">
</div>
</form>
I checked and are returning FireStore values, but I'm not able to return the screen.
Upvotes: 1
Views: 3632
Reputation: 173
ERROR Error: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field administrador)
at new FirestoreError (error.js:149)
at ParseContext.createError (user_data_converter.js:162)
at UserDataConverter.parseScalarValue (user_data_converter.js:439)
at UserDataConverter.parseData (user_data_converter.js:339)
at eval (user_data_converter.js:362)
at Object.forEach [as c] (obj.js:49)
at UserDataConverter.parseObject (user_data_converter.js:361)
at UserDataConverter.parseData (user_data_converter.js:331)
at UserDataConverter.parseSetData (user_data_converter.js:212)
at DocumentReference.set (database.js:489)
perfilUser.component.html:
<form [formGroup]="perfilForm" novalidade>
<div class="row">
<div class="form-group col-12 col-sm-12 col-md-7 col-lg-4 col-xl-4">
<label for="name">Nome*</label>
<input type="text" class="form-control" [(ngModel)]="perfil.nome" formControlName="nome" placeholder="Nome completo">
</div>
<button class="btn btn-success" type="button" (click)="saveProfile()">Save</button>
</form>
perfilUser.component.ts:
perfil: Perfil = new Perfil();
saveProfile() {
this.authService.createProfile(this.perfilForm.value);
}
authService.ts:
@Injectable()
export class AuthService {
perfil: Observable<Perfil[]>;
userId: string;
constructor(private afs: AngularFirestore) {
this.afAuth.auth.onAuthStateChanged((user) => {
if (user) {
this.userId = user.uid;
}
})
}
createProfile(perfil: Perfil) {
const userRef: AngularFirestoreDocument<Perfil> = this.afs.doc(`perfil/${perfil.userId}`);
return userRef.set(perfil);
}
perfilModel.ts:
export class Perfil {
nome: string;
..... : string;
..... : string;
}
the rest of the code is at the beginning of the question
Upvotes: 0
Reputation: 1393
If you want the observable to populate your form, you have to call the buildForm
inside the subscribe
or at least assign values inside the subscribe
. Here is an example
perfil.component.ts
nome:string;
constuctor(){
this.perfilForm = new FormGroup({
"nome": new FormControl(this.nome)
});
}
ngOnInit() {
const subscribe = this.authService
.getPerfil()
.subscribe((p: any) => {
subscribe.unsubscribe();
this.nome = p.nome;
})
}
perfil.component.html
<form [formGroup]="perfilForm" novalidade>
<div class="row">
<div class="form-group col-12 col-sm-12 col-md-7 col-lg-4 col-xl-4">
<label for="name">Nome*</label>
<input type="text" class="form-control" formControlName="nome" placeholder="Nome" [(ngModel)]="nome">
</div>
</div>
</form>
Upvotes: 0
Reputation: 6311
use patchValue inside the subscribe
this.authService
.getPerfil()
.subscribe((p: any) => {
this.perfilForm.patchValue({'nome' : p.nome})
})
Upvotes: 1