Friday, June 20, 2014

Friend Request in JavaScript using Parse.com - Part 1

This is a follow-on from my last post, almost a year ago. Yes, I know, I should post more often, anyway...

First off we need to define some things that are common to all the code blocks:
// fake an enum, allows auto-complete for some editors
var RequestStatus = {
  requested: 'requested', 
  rejected: 'rejected',
  approved: 'approved'
};
// define our Parse Class
var FriendRequest = Parse.Object.extend('FriendRequest');
var currentUser = Parse.User.current();
I will also assume you have jQuery available.

Now lets go through our requirements.

Find a person (highlight existing status)

// for simplicity lets assume we're doing a search for people
// in the same "area" as us, lets also assume you're aware of
// case-sensitive issues and created a "search_Area" property
// forced to lower-case (using a before-save Cloud Function)

var userQuery = new Parse.Query(Parse.User);
userQuery.equalTo('search_Area', currentUser.get('search_Area'));

// shared array we'll store details in
var userList = [];
// dictionary we'll use for easier updating
var userDict = [];
userQuery.find().then(function(users) {
  // lets just extract the "id" and "username" first
  for (var i in users) {
    var userInfo = {
      id: users[i].id, 
      name: users[i].get('username')
    });

    userList.push(userInfo);
    userDict[userInfo.id] = userInfo;
  }

  // now we need to attach a status to each one
  var myRequests = new Parse.Query(FriendRequest);
  myRequests.equalTo('fromUser', currentUser);
  myRequests.equalTo('toUser', users);

  var requestsToMe = new Parse.Query(FriendRequest);
  requestsToMe.equalTo('fromUser', users);
  requestsToMe.equalTo('toUser', currentUser);

  var combinedRequests = Parse.Query.or(myRequests, requeststoMe);

  return combinedRequest.find();
}).then(function (requests) {
  for (var i in requests) {
    var request = requests[i];
    var status = request.get('status');

    if (request.get('fromUser').id == currentUser.id) {
      // set status from my perspective
      userDict[request.get('toUser').id].statusMessage = 
        status == RequestStatus.approved ? 'Already my friend' :
        status == RequestStatus.rejected ? 'I rejected them' :
        status == RequestStatus.requested ? 'Waiting for them to reply' :
        'Unknown status';
    } else {
      // set status from the other person's perspective
      userDict[request.get('fromUser').id].statusMessage = 
        status == RequestStatus.approved ? 'Already my friend' :
        status == RequestStatus.rejected ? 'They rejected me' :
        status == RequestStatus.requested ? 'Waiting for me to reply' :
        'Unknown status';
    }
  }

  // at this point you can render the userList
  for (var i in userList) {
    var userInfo = userList[i];
    // assuming you have a container DIV with id="possibleFriends"
    $('#possibleFriends').append(
      '<div data-user-id="' +  userInfo.id + '"'
      + ' class="possibleFriend">'
      + userInfo.userName
      // not all will have a status, so handle that
      + (userInfo.status ? ' - ' + userInfo.status : '')
      + '</div>');
  }
});
With the above you can extend it however you like to allow sorting etc, it is just the bare-bones implementation.

No comments: