Reputation: 6029
I'm experiencing a very strange issue, I retrieve the users profile from Firebase
inside this profile is an Photo Object basically an array of photos the user has uploaded.
My get Profile method:
getUserProfile(): Observable<User> {
var userId = null;
var auth = this.af.auth.subscribe(user => {
userId = user.uid;
});
auth.unsubscribe();
return this.af.database.object('/users/' + userId)
.map(pro => new User(
pro.$key,
pro['email'],
pro['gender'],
pro['last_name'],
pro['first_name'],
pro['display_name'],
pro['photos'],
pro['hobbies']))
}
My user class is as follows:
export class User {
public constructor(
public userId: string,
public email: string,
public gender?: string,
public last_name?: string,
public first_name?: string,
public display_name?: string,
public photos: Photo[] = [],
public hobbies: Hobbies[] = [],
) { }
}
Inside my component I call the getUserProfile as so:
this.userSubscription = this.profileService.getUserProfile().subscribe(profile => {
console.log(profile.photo);
});
When I write console.log(profile.photos);
I see the following:
Yet when I try to loop through this collection by doing the following:
for(var i = 0; i < profile.photos.length; i++){
console.log('here');
}
Nothing is written to the console, even when I do the following:
console.log(profile.photos.length);
it says undefined....
I'm not entirely sure what is going wrong, can anyone spot the reason into why I can't loop through the photo array and access the properties?
Upvotes: 0
Views: 273
Reputation: 12434
The profile.photos
is an object and not an array. Try to change the photos
member on you interface to:
public photos: {[index: string]: Photo} = {}
So, to iterate this object you can do:
for(let key in profile.photos) {
let photo = profile.photos[key];
//...
}
UPDATE
If you want to see other options to get all property values from a javascript Object see this: How to get all properties values of a Javascript Object (without knowing the keys)?
Upvotes: 1
Reputation: 31873
All you need is something like this, give it a try
service.ts
import 'rxjs/add/operator/mergeMap';
import {User} from './user';
export default class Service {
getUserProfile(): Observable<User> {
return this.af.auth.flatMap(({ id }) =>
this.af.database.object('/users/' + id)
);
}
}
component.ts
import Service from './service';
export class Component {
constructor(readonly service: Service) { }
ngOnInit() {
this.service.getUserProfile().subscribe(({ photos = [] }) => {
photos.forEach(console.log);
});
}
}
user.ts
export interface User {
userId: string,
email: string,
gender?: string,
last_name?: string,
first_name?: string,
display_name?: string,
photos: Photo[],
hobbies: Hobbies[];
}
No manual deserialization lining up keyed values by name to shove them into a meaningless User class
, just use an interface
. No mutable security variables. No subscriptions to worry about, for the time being. Just get the basic problem right.
Upvotes: 0
Reputation: 1525
for syntax is breaking your code.Try this.
this.userSubscription = this.profileService.getUserProfile().subscribe(profile => {
console.log(profile.photo);
for (let entry of profile.photo) {
console.log(entry);
}
});
Reference : https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html
Upvotes: 0