-2

How do I properly access this.existingUsers in the formBuilder? Now the console.log(value) doesn't show up in console. console.log(this.id) returns the correct parameter.

export class UserComponent implements OnInit {

  existingUser: any = {};

      ngOnInit() {

        this.activatedRoute.params.subscribe((params: Params) => {
          this.id = params['id'];
          console.log(this.id);
          this.db.object(`/users/${this.id}`).map(value => {
            console.log(value);
            this.existingUser = value;
          })
        });

        console.log(this.existingUser);

        this.userForm = this.formBuilder.group({
          first_name: [this.existingUser.first_name, Validators.required],
        })
      };

}
Ciprian
  • 3,066
  • 9
  • 62
  • 98
  • You don't show what `this.db.object` might be, but you never `subscribe` to what it returns. Also you seem to be assuming that the `existingUser` will somehow be available in subsequent lines - if that was the case, *you wouldn't need the observable*. – jonrsharpe Aug 18 '17 at 21:33
  • Possible duplicate of [How to return value from an asynchronous callback function?](https://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function) –  Aug 19 '17 at 05:14

2 Answers2

0

I'm not completely clear on what you are trying to do ... but you probably need that code within the .map method. Like this:

export class UserComponent implements OnInit {

  existingUser: any = {};

  ngOnInit() {

    this.activatedRoute.params.subscribe((params: Params) => {
      this.id = params['id'];
      console.log(this.id);
      this.db.object(`/users/${this.id}`).map(value => {
        console.log(value);
        this.existingUser = value;
        console.log(this.existingUser);

         this.userForm = this.formBuilder.group({
          first_name: [this.existingUser.first_name, Validators.required],
        })
      })
    });

  };

}

Or put that code in a method that is called from here.

UPDATE: Here is an example from my application that does something similar:

ngOnInit(): void {
    this.productForm = this.fb.group({
        productName: ['', [Validators.required,
                           Validators.minLength(3),
                           Validators.maxLength(50)]],
        productCode: ['', Validators.required],
        starRating: ['', NumberValidators.range(1, 5)],
        tags: this.fb.array([]),
        description: ''
    });

    // Read the product Id from the route parameter
    this.route.params.subscribe(
        params => {
            let id = +params['id'];
            this.getProduct(id);
        }
    );
}

getProduct(id: number): void {
    this.productService.getProduct(id)
        .subscribe(
            (product: IProduct) => this.onProductRetrieved(product),
            (error: any) => this.errorMessage = <any>error
        );
}

onProductRetrieved(product: IProduct): void {
    if (this.productForm) {
        this.productForm.reset();
    }
    this.product = product;

    if (this.product.id === 0) {
        this.pageTitle = 'Add Product';
    } else {
        this.pageTitle = `Edit Product: ${this.product.productName}`;
    }

    // Update the data on the form
    this.productForm.patchValue({
        productName: this.product.productName,
        productCode: this.product.productCode,
        starRating: this.product.starRating,
        description: this.product.description
    });
    this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}

You can find the full set of code here: https://github.com/DeborahK/Angular2-ReactiveForms (in the APM folder)

DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • I'm trying to use the same component to create / update users. That's why I subscribe to this.activatedRoute.params . I left out the if in my question. If this.id is other than create, and if this.db.object(/users/${this.id}) returns a user, the form is populated with the user's information – Ciprian Aug 19 '17 at 04:22
  • All of that logic could then go into a method called from within the .map function (after the `this.existingUser = value` statement for example. – DeborahK Aug 19 '17 at 05:10
  • And if you'd like to see a full code example of doing create, update, delete, read (CRUD), I have a full sample application here: https://github.com/DeborahK/Angular2-ReactiveForms (in the APM folder) – DeborahK Aug 19 '17 at 05:11
  • Not sure why your answer got down voted. Thank you for the example. – Ciprian Aug 19 '17 at 09:49
-2

You are trying to get asynchronous data before it has been set.

When something is asynchronous it will run at a future time, and subscriptions are asynchronous.

Everything within the subscribe function runs after the ngOnInit has already completed. Which means, you are currently trying to access the first_name before the existing_user has even been set.

Try moving your this.userForm stuff into the subscribe function like this:

this.activatedRoute.params.subscribe((params: Params) => {
      this.id = params['id'];
      console.log(this.id);
      this.db.object(`/users/${this.id}`).map(value => {
        console.log(value);
        this.existingUser = value;
      })
      console.log(this.existingUser);

      this.userForm = this.formBuilder.group({
        first_name: [this.existingUser.first_name, Validators.required],
      })
    });
ed-tester
  • 1,596
  • 4
  • 17
  • 24