1

I am creating an app using angular 4.0.2, angularfire2, and firebase, off course. What the problem is I am not able to use the data from angularfire2 and set it as default input value of an input used in model-driven or reactive form. Here is my code for add-invoice.component.ts

ngOnInit(){
  const datafetch = firebase.database().ref().child('/invoices').orderByKey().limitToLast(1).once('value').then(snapshot => {
    const names = [];
    snapshot.forEach(function(childSnapshot) {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      names.push(childSnapshot.val());
    });
    this.patchValues(names);
  });

  this.invoiceForm = this.fb.group({
    invoiceno: '',
    itemRows: this.fb.array([this.initItemRows()])
  });
}

patchValues(names){
  this.invoiceForm.patchValue({
    invoiceno: names.invoiceno
  });
  console.log(names);
}

Array being Shown up in console.
Console Image

Here is my form i.e. add-invoice.component.html

<div class="form-group col-md-2">
<label>Invoice No.</label>
<input formControlName="invoiceno" class="form-control">

Climb Tree
  • 460
  • 1
  • 5
  • 15
  • @AJT_82 Do you need the output over there in console? If so, I can provide. It's just an Array I can send you the image. If you really need. – Climb Tree Apr 20 '17 at 19:28
  • This is an async issue, if this would be the only problem, it would be a duplicate of this: http://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2 :) – AJT82 Apr 20 '17 at 19:30
  • Sorry @AJT_82 I am very new to angular 4 and typescript. Can you please explain me in detail, as you did in my previous question? Please. I am not getting anything going on in the question you asked me to view. – Climb Tree Apr 20 '17 at 19:32
  • In short this just means that anything you want to do with your data that you receive, you have to do inside the callback (subscribe). Since you want to set the formvalues with the data you receive, you can look at this: http://stackoverflow.com/questions/43266967/angular-2-4-cant-read-object-in-initform/43279908#43279908 In that answer we call `patchForm` inside `subscribe`. So your setup would be pretty much the same, just change variable names :) – AJT82 Apr 20 '17 at 19:39
  • @AJT_82 In my case the data is not being provided. The console.log(name) returns undefined. The data is under ZoneAwarePromise. This is the problem. – Climb Tree Apr 20 '17 at 19:42
  • Hmm... you have written that inside the subscribe you get the value fine in console log? From your code: `console.log(name); // Here is the correct output I need below` Or am I misunderstanding something now, it wouldn't surprise me :D – AJT82 Apr 20 '17 at 19:44
  • console.log(name) is not in subscribe. The code I posted is the actual code. @AJT_82 – Climb Tree Apr 20 '17 at 19:46
  • Right, see, I'm getting tired I think :D I see now that you are using promises. Well, the point is still the same, you need to manipulate your data inside `then`, not outside, because the `name`will be empty/undefined/null outside `then`, just like your code suggests :) – AJT82 Apr 20 '17 at 19:52
  • @AJT_82 Please if you are getting tired, take a rest. You have to help many others tomorrow :D. Let's talk about this tomorrow. I am also very tired. Hehe... – Climb Tree Apr 20 '17 at 19:53
  • @AJT_82 Take a look in the changes I made in the code. It still return the error: Cannot read property of patchValues 'undefined' – Climb Tree Apr 21 '17 at 03:54
  • Looks better, but seems still there is an issue... can you make sure, whether the error is `Cannot read property of patchValues 'undefined'` or `Cannot read property of patchValue 'undefined'`? (notice the `s`) Just to make sure, so we can determine where exactly the error is thrown :) – AJT82 Apr 21 '17 at 07:49
  • Yes @AJT_82 The error is `Cannot read property of patchValues 'undefined'` – Climb Tree Apr 21 '17 at 12:01
  • Hey @AJT_82 are you there? – Climb Tree Apr 21 '17 at 12:44
  • Yes, I was just about to get back to you :) I think you are loosing the scope of `this` since you are using `function` instead of fat-arrow-syntax. so replace both places where you are using function, so it would be for the first one: instead of `.then(function(snapshot)` do: `then(snapshot => { .....more code here... }` – AJT82 Apr 21 '17 at 12:50
  • @AJT_82 I just did this. Now there is no error :) in console. and array is being shown over there but the patchValue still didn't worked. The `invoiceForm.value` turned to this `{ "date": "", "itemRows": [ { "itemname": "", "itemqty": "", "itemrate": "" } ] }` and Array is something like this I just showed in my code. Just a sec I am editting my post. :D – Climb Tree Apr 21 '17 at 12:55
  • Thanks @AJT_82 I got that – Climb Tree Apr 21 '17 at 13:01
  • @AJT_82 You have helped me a lot in my app. Can you please answer this question? So that you can get a reward for your priceless effort – Climb Tree Apr 21 '17 at 13:26
  • Sure thing, done :D and +1 for your question :) – AJT82 Apr 21 '17 at 13:39

1 Answers1

1

The reason for that this.patchValues(names); gave you error

Cannot read property of patchValues 'undefined'

was because you are using function in your code, instead of fat-arrow-syntax. With fat-arrow you keep the context of this.

So instead of this piece of code (from your unedited post):

const datafetch = firebase.database().ref().child('/invoices').orderByKey().limitToLast(1).once('value').then(function(snapshot) {
  const names = [];
  snapshot.forEach(function(childSnapshot) {
    var childKey = childSnapshot.key;
    var childData = childSnapshot.val();
    names.push(childSnapshot.val());
  });
  name.push(names);
  console.log(name); // Here is the correct output I need below
});

You need to use fat-arrow syntax and then this will not be undefined:

  const datafetch = firebase.database().ref().child('/invoices').orderByKey().limitToLast(1).once('value').then(snapshot => {
    const names = [];
    snapshot.forEach(childSnapshot => {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      names.push(childSnapshot.val());
    });
    this.patchValues(names);
  });
Community
  • 1
  • 1
AJT82
  • 60,574
  • 21
  • 115
  • 147