Reputation: 1786
It seems part of my problem is the way stuff is loaded. As i call the createForm function in my constructor it trys to access the this.paswdProfile.numbers and other variables which are part of the ngOnInit and are not avail yet so it fails. if i move the form to the ngOnInit it complains about no FormGroup etc. So how can i ensure that the form fields are created after the passwdProfile has data ?
import {IBucket} from '../../../../models/bucket';
import { Component, OnInit, Inject, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { AdminService } from '../../../../services/admin.service';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material';
import { Observable } from 'rxjs';
import { CouchbaseLookupService} from '../../../../services/couchbase-lookup.service';
import { takeWhile } from 'rxjs/operators';
import { ToasterService} from 'angular2-toaster';
import { CustomValidators } from './custom-validators';
import { IPasswordProfile } from '../../../../models/admin'
@Component({
selector: 'app-password',
templateUrl: './password.component.html',
styleUrls: ['./password.component.scss']
})
export class PasswordComponent implements OnInit {
public passwordForm: FormGroup;
alive = true;
paswdProfile$: Observable<IPasswordProfile>
paswdProfile: IPasswordProfile
constructor(@Inject(MAT_DIALOG_DATA) public data: any, private dialogRef: MatDialogRef<PasswordComponent>,
private adminService: AdminService, private route: ActivatedRoute, private cbLookupService: CouchbaseLookupService,
private router: Router, private dialog: MatDialog, private toasterService: ToasterService, private fb: FormBuilder) {
this.passwordForm = this.createPasswordForm()
}
ngOnInit() {
this.paswdProfile$ = this.adminService.getPasswordProfile("8084ea42-633e-4c28-bc7a-372aa58a4d1c")
this.paswdProfile$.subscribe(res => {this.paswdProfile = res[0]})
console.log(this.paswdProfile)
}
createPasswordForm(): FormGroup {
return this.fb.group(
{
oldPassword : [ null, Validators.compose([Validators.required])],
newPassword: [
null,
Validators.compose([
Validators.required,
// check whether the entered password has a number
CustomValidators.patternValidator(/\d/g, this.paswdProfile.numbers , {
hasNumber: true
}),
// check whether the entered password has upper case letter
CustomValidators.patternValidator(/[A-Z]/g, this.paswdProfile.upperCase, {
hasCapitalCase: true
}),
// check whether the entered password has a lower case letter
CustomValidators.patternValidator(/[a-z]/g, this.paswdProfile.lowerCase, {
hasSmallCase: true
}),
// check whether the entered password has a special character
CustomValidators.patternValidator(
/[ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/g, this.paswdProfile.specialChar ,
{
hasSpecialCharacters: true
}
),
Validators.minLength(this.paswdProfile.minChar)
])
],
confirmPassword: [null, Validators.compose([Validators.required])]
},
{
// check whether our password and confirm password match
validator: CustomValidators.passwordMatchValidator
}
);
}
}
Upvotes: 1
Views: 2070
Reputation: 1652
In order to access an observable value you need to use the https://angular.io/api/common/AsyncPipe if you are using the value in the template.
If you want to access it in the .ts file you need to subscribe to it and wait for it to resolve like:
this.paswdProfile$.subscribe(profile => {
const numbers = profile.numbers;
});
Upvotes: 0
Reputation: 106
You don't get a reference to the object. You get a reference to the Observable. You need to subscribe to the Observable and store the result. This is done asynchronously.
this.adminService.getPasswordProfile("8084ea42-633e-4c28-bc7a-372aa58a4d1c")
.subscribe(profile => this.paswdProfile$ = profile);
Upvotes: 2