skip to Main Content

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

}

2

Answers


  1. 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.
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search