1

I need to code some object array and array of interface to do my project using Angular app, but I have to face the error about the value there. I have tried 3 code alternatives:

First

I dont understand why the object does not return.

This is my output:

enter image description here

And here is the code :

Home Component

  onSearch(){
this.indexingQuery(this.search); // for spliting the input user and check the word
let cek = this.dbService.checkTerm();
cek.then(
  (data)=>{
    for(var index in this.term) { 
      let a = this.dbService.ReadTermPerDocumentFreq(index);
      console.log(a);
      console.log("a");
      this.termFA.push(a);
    }
    this.termFA.forEach(element=>{
      console.log(element);
      console.log(element.freq);
    });

  }
);}

Database Service

ReadTermPerDocumentFreq(kata:string):TermFreqAll{
let temp:TermFreqAll ;
this.afDb.database.ref('/term_freq_all/'+kata).
once('value', function(snapshot){
  let userData : any= snapshot.val();
  temp = new TermFreqAll(
    userData.word,
    userData.doc_freq,
    userData.freq,
    userData.docs
  );
  console.log("temp");
  console.log(temp);
  console.log("temp");
});
console.log(temp);
return temp;}

Second

If I change that code like this. It will be return, but I cannot get the property.

This is the output:

enter image description here

And the code :

Home Component

onSearch(){
this.indexingQuery(this.search);
let cek = this.dbService.checkTerm();
cek.then(
  (data)=>{
    for(var index in this.term) { 
      let a = this.dbService.ReadTermPerDocumentFreq(index);
      this.termFA.push(a);
      console.log(a);
      console.log("a");
    }
    this.termFA.forEach(element=>{
      console.log("Arrghh");
      console.log(element);
      console.log(element.freq);
    });

  }
);}

Database Service

ReadTermPerDocumentFreq(kata:string):TermFreqAll{
let temp:TermFreqAll = new TermFreqAll();
this.afDb.database.ref('/term_freq_all/'+kata).
once('value', function(snapshot){
  let userData : any= snapshot.val();
  temp.freq = userData.freq;
  temp.docs = userData.docs;
  temp.doc_freq = userData.doc_freq;
  temp.word = userData.word;
  console.log("temp");
  console.log(temp);
  console.log("temp");
});
console.log(temp);
return temp;}

Third

I try to return promise from database service. The value is can push into the TermFA array but cannot get the value in looping. Same case as the second try. It says that the array length is 0.

This is my output

enter image description here

And this is the code :

Home Component

onSearch(){
this.indexingQuery(this.search);
let cek = this.dbService.checkTerm();
cek.then(
  (data)=>{
    for(var index in this.term) { 
      console.log(index);
      let a = this.dbService.ReadTermPerDocumentFreq(index);
      a.then((data)=>{
        console.log("data");
        console.log(data);
        let b = this.termFA.push(data);
      });
    }
    console.log("this.termFA");
    console.log(this.termFA);
    this.termFA.forEach(element=>{
      console.log("Arrghh");
      console.log(element);
      console.log(element.freq);
    });
    console.log("this.termFA2");
    console.log(this.termFA);
    for(let i in this.termFA){
      console.log("loop");
      console.log(this.termFA[i]);
      console.log(this.termFA[i].freq);
    }
  }
);}

Database Service

ReadTermPerDocumentFreq(kata:string):Promise<TermFreqAll>{
return new Promise((resolve, reject)=>{
  this.afDb.database.ref('/term_freq_all/'+kata).once("value",snapshot => {
      let userData : any= snapshot.val();
      // console.log(userData);
      if (userData){
        console.log("userdata");
        console.log(userData);
        let temp : TermFreqAll = new TermFreqAll();
        temp.freq = userData.freq;
        temp.docs = userData.docs;
        temp.doc_freq = userData.doc_freq;
        temp.word = userData.word;
        // console.log("true");
        resolve(temp);
      }
      else{
        let temp : TermFreqAll = new TermFreqAll();
        resolve(temp);
      }
  }).catch(error=>{
      let temp : TermFreqAll = new TermFreqAll();
      resolve(temp);
  });
});}
2
  • thanks for improve my words @xg.plt.py Commented May 11, 2018 at 1:23
  • No problem! I don't really know much about angular nor typescript, and I am not sure but I think missed including your desired output in addition to the code you have tried Commented May 11, 2018 at 1:25

1 Answer 1

2

The problem with the last try is that you are calling an asynchronous database function inside your first loop. You're expecting the results of it to be already existing after each loop, but they are not, because the then is function is asynchronous and will probably be called later on. Now instead of waiting for the results, the loop goes on triggering more database calls, and when it's finished you are trying to access the termFA array, but probably none of the result functions that fill this array were have been executed yet.

Here's an option for this problem. Instead of trying to react to the promises inside your first loop directly, you could collect those promises and execute them with a Promise.all() call. This way, you can easily react to all promise returns at once and have a finished and filled array of results at hand.

let promiseArray:Promise<TermFreqAll>[]=[];
for(var index in this.term) { 
  console.log(index);
 // save it in an array to combine all executes after the loop has finished
 promiseArray.push(this.dbService.ReadTermPerDocumentFreq(index));
}

// now execute them and wait till they are all returned
Promise.all(promiseArray).then(values=>{
  // when everything has returned, you can react to it as if you had filled your array;
  // "values" is an array of all results, what probably is equal to your "termFA" array
  values.forEach(element=>{
    console.log("Arrghh");
    console.log(element);
    console.log(element.freq);
  });
}

For more on the Promise.all function you can check this out.

Hope this helps. Let me know if something is not clear.

Sign up to request clarification or add additional context in comments.

3 Comments

it runs like before sir @BenediktSchmidt . i have tried = - i add type in let promiseArray=[]; to be like this let promiseArray:TermFreqAll=[]; - change this.termFA to be values from code above and the result same and the length of promiseArray is 0
i try to call this again let a = this.dbService.ReadTermPerDocumentFreq(index); a.then((data)=>{ //to get atribut }); it works. but why i have to call that first. that function just return promise<boolean>
I've updated my code. The array should be of type Promise<TermFreqAll>[], not sure if this fixes the problem. And yeah, we're looping over the values after Promise.all() call of course.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.