简体   繁体   中英

Problem with TS2339 Property xxx does not exist on type Observable

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
      }
    );
  }


}

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);

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;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM