Home > database >  Async function call not yielding any results to parent calling function
Async function call not yielding any results to parent calling function

Time:01-14

I am trying to retrieve a document field value given a documentID. I have solved the db calling part, but I cannot send the data back up. It's almost as if the function this.userDbService.getVendorNameFromUserId below isn't being called at all.

Here is the parent function:

async getVendorName() {
  let name;

  //blindtiger not going here.

  //calling to 'private userDbService: UserDbService'
   name = await this.userDbService.getVendorNameFromUserId('2OD1yTnMrecMgqljvHFHDjug1VT2');
   console.log(name);
   return name.toString();}

and here is the function getVendorNameFromUserId(''):

 async getVendorNameFromUserId(id: string): Promise<string> {
    let vendorName = '';
    const userCollectionRef = await doc(this.store, 'clients/'   id);


    await docData(userCollectionRef, {idField: 'id'}).forEach(el => {

      //correctly is 'blindtiger' from db call.
      console.log(el['user'].companyName.toString())
      return el['user'].companyName.toString();
    });
    //parent function doesn't yield any results - as if this is not called.
    // It should yield 'blindtiger' here.
    return 'NOT FOUND';
  } 

getVendorName() is being called within the constructor of a typescript file, the value of this function result is then being used to get all products for that vendor name.

  constructor(private shopifyService: ShopifyService, private userDbService: UserDbService, private modalService: NgbModal, private userAuthService: UserAuthService, private itemDb: ItemDbService) {
    let vendorName: string;

    const name = this.getVendorName();
    console.log(name);
    this.getAllProducts(name).then(result => {
      console.log(result);
      this.itemsToSell = result;
    });
  }`

I have a feeling I am missing something async related - buy would love any advice on why the value 'blindtiger' isn't even being passed up the chain at all.

I have tried adding async await to the function call - getVendorNameFromUserId(). If I remove the await keyword in from of docData() here:

    await docData(userCollectionRef, {idField: 'id'}).forEach(el => {

      //correctly is 'blindtiger' from db call.
      console.log(el['user'].companyName.toString())
      return el['user'].companyName.toString();
    });`

I get the result 'NOT FOUND' - which suggests this passes data up the chain correctly. I am thinking there is a problem with this function not being waited on by the calling function which looks like this:

 async getVendorName() {
    let name;

    //blindtiger not going here.

    //calling to 'private userDbService: UserDbService'
    name = await this.userDbService.getVendorNameFromUserId('2OD1yTnMrecMgqljvHFHDjug1VT2');
    console.log(name);
    return name.toString();
  }

CodePudding user response:

You have a return in your foreach : it will return result for the foreach, not the getVendorNameFromUserId. Use regular forof instead

async getVendorNameFromUserId(id: string): Promise<string> {
  let vendorName = '';
  const userCollectionRef = await doc(this.store, 'clients/'   id);


  const data = await docData(userCollectionRef, {idField: 'id'});
  for (const el of data) { 
    //it will return the first found. Don't you need condition to search from criterias?
    //correctly is 'blindtiger' from db call.
    console.log(el['user'].companyName.toString())
    return el['user'].companyName.toString();
  }
  //parent function doesn't yield any results - as if this is not called.
  // It should yield 'blindtiger' here.
  return 'NOT FOUND';
}
  • bonus : avoid async in constructors, for async init you can use APP_INITIALIZER in Angular.

CodePudding user response:

I assume that docData() returns an array where you just need the first value, since the method-signature reads getVendorNameFromUserId and you pass exactly one id. Therefore your code could look as follows:

async getVendorName() {
    const name = await this.userDbService.getVendorNameFromUserId('2OD1yTnMrecMgqljvHFHDjug1VT2');
    console.log('name', name);
    return name;
}

async getVendorNameFromUserId(id: string): Promise<string> {
    const userCollectionRef = await doc(this.store, 'clients/'   id);
    console.log('userCollectionRef', userCollectionRef);

    const resultArray = await docData(userCollectionRef, {idField: 'id'});
    console.log('resultArray', resultArray);

    // Get the first element from array, given the array has at least one element
    const vendorName = resultArray?.map(el => el.user.companyName.toString())?.[0];
    return vendorName ?? 'NOT FOUND';
}

Please note: You don't need to write toString() in getVendorName(), since getVendorNameFromUserId() already returns a promise of type string.

  • Related