Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Anuj Verma
Anuj Verma
11,825 Points

PFQuery to find all fields in profile in Ribbit

I'm pretty sure my query is not correct here. I have created a new ProfileViewController and I am trying to load all the fields of a selectedUserId which is stored as userId. This below is in my ProfileViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    PFQuery *query = [PFUser query];
    [query whereKey:@"objectId" equalTo:self.userId];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }

        else {
            self.userId = (NSString *)objects;
            [self.tableView reloadData];
        }
    }];
}

I am also then struggling how I would get all the separate fields to show up in the cellForRowAtIndexPath section.

I got stuck again Ben Jakuben :/

Anuj Verma
Anuj Verma
11,825 Points

i get confused with the UI on adding comments to answers and responses to those. Just a suggestion but I think could be better if there was add comment at the bottom as opposed to the top of each thread.

2 Answers

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Your query looks okay, but let's take a look at the code inside your block.

^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }

        else {
            self.userId = (NSString *)objects;
            [self.tableView reloadData];
        }

The block will be called with an array of PFUser objects if it succeeds, or else the NSError variable will have a value if it fails. Your error check looks fine.

But in the else block, you are trying to convert that array of PFUser objects (objects) into an NSString. That's the wrong data type. To make this work, you'd need to create an array of PFUser objects and store the objects parameter in there, like in FriendsViewController:

In the header:

@property (nonatomic, strong) NSArray *users;

Then you'd need to get the first (only) user from the array:

else {
    self.users = objects;
    PFUser *foundUser = [self.users objectAtIndex:0];
}

Instead, though, have a look at this PFQuery method to get a specific user: http://parse.com/docs/osx/api/Classes/PFQuery.html#//api/name/getUserObjectWithId:

Lastly, if you are displaying one user, you might not want to use a table view in your ProfileViewController. You can just lay out the fields individually and populate them each from the PFUser object you end up getting.

Hope this helps...

Anuj Verma
Anuj Verma
11,825 Points

So that makes sense to me I didn't do the getUserObjectWitId. I'll play with that after I get it this way. My viewDidLoad now looks like this:

- (void)viewDidLoad
{
    [super viewDidLoad];

    PFQuery *query = [PFUser query];
    [query whereKey:@"objectId" equalTo:self.userId];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }

        else {
            self.users = objects;
            PFUser *foundUser = [self.users objectAtIndex:0];
        }
    }];
}

I then made my ProfileViewController a UIViewController (instead of a TableViewController). My question now is to get all the fields of a user to show up, do I have to create IBOutlet UILabels? If so, I'm not sure how to get them to show up in the ViewDidLoad in the ProfileViewController. I know I have to populate them from the foundUser we just created.

Sorry for all the questions, and really appreciate all your help.

Ben Jakuben
Ben Jakuben
Treehouse Teacher

I'm glad to help and glad you're working on this extra credit! Doing independent work like this is really the best way to learn.

Your plan sounds good: drag UILabels into your view controller and create IBOutlets. Then you can reference the properties in your viewDidLoad method after you get the data from the PFUser.

The following is untested from memory, so you might need to change details:

- (void)viewDidLoad {
  [super viewDidLoad];

  PFUser *user = // query to get the user from Parse using self.selectedUserId
  // Then add lines like these in the block, which will be executed
  // once you've found the user and set the *user variable:
  self.usernameLabel = user.username; // will be inside the block
  self.emailLabel = user.email; // will be inside the block
}
Anuj Verma
Anuj Verma
11,825 Points

Putting my comment in the right part of the thread heh, sorry for all the wrong posts in the wrong sections!

- (void)viewDidLoad
{
    [super viewDidLoad];

    PFQuery *query = [PFUser query];
    [query whereKey:@"objectId" equalTo:self.userId];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }

        else {
            self.users = objects;
            PFUser *foundUser = [self.users objectAtIndex:0];
            self.username = foundUser.username;
        }
    }];
}

My viewDidLoad looks like this, which I think is correct, but I get this warning "Incompatible pointer type assigning 'UILabel *' from 'NSString'. I must have something wrong! :/