Angular observables piping
What do you mean with &quot;efficient&quot; in this case?
From the performance perspective its slow, because it handles one element after the other and for handling one element it needs to wait for an async call.
As a result the browser will note be able to execute multiple requests at once.
You could try to move the getImage request into the html with the async pipe.
Then the browser will be able to fire multiple requests simultaniously.
Beside that i personaly would divide the code in a few methods. So it would look like this:
__HTML__
&lt;img [src]=&quot;getImage(link.img) | async&quot;



__TypeScript__
interface Link{
    id: string,
    img: string,
    name: string,
    bio: string
};

...
this.links = this.getLinks(userRef);
...

private getLinks(userRef: ??? ): Link[] {
    return userRef.collection('links', ref.where('pendingRequest', '==', false)).get()
        .pipe(
            map(querySnap =&gt; mapSnapToLinks(querySnap))
        )
}

private mapSnapToLinks(querySnap: ???):Link[]{
    querySnap.forEach(async doc =&gt; {
        const val = doc.get('otherUser').get().then(userData =&gt; this.mapUserToLink(userData));
        ret.push(val);
    });
}

private mapUserToLink(userData): Link {
    return {
        id: userData.id,
        img: userData.get('profilepic'),
        name: userData.get('name'),
        bio: userData.get('bio')
    }
}