Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async function call not yielding any results to parent calling function

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

docData returns an observable.

const data = await docData(userCollectionRef, {idField: 'id'}).pipe(take(1)).subscribe(user => {
  vendorName = user['user'].companyName;

  //does not yield blind tiger
  console.log({dataDone: vendorName});
})

//does yield blind tiger
console.log({dataAfter: vendorName})
return vendorName['user'].companyName

}

like image 656
Will Angell-James Avatar asked Mar 19 '26 04:03

Will Angell-James


1 Answers

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 firstValueFrom(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.

like image 107
kellermat Avatar answered Mar 20 '26 18:03

kellermat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!