Get user relation users in parse query ionic4 - parse-platform

I have the following parse query:
loadAllFriends(params: any = {}): Promise<User[]> {
const page = params.page || 0;
const limit = params.limit || 20;
const query = new Parse.Query(User);
const user = Parse.User.current();
const relation = user.relation('likes');
query.equalTo('likes', user);
query.descending('updatedAt');
query.skip(page * limit);
query.limit(limit);
return query.find();
}
...and i load the data in page.ts like:
const users = await this.userService.loadAllFriends(this.params);
console.log(users);
for (let user of users) {
this.users.push(user);
}
... So this code it queries const user = Parse.User.current(); in likes relation column, checks if user is there and returns the results.
I need exact the opposite, with the anterior query i get the friends, but i need to get the followers. The followers are stored in user -> likes relation column:
How can i query user like:
const user = Parse.User.current();
query.equalTo('objectId', user.id);
... and here get the likes relation data from this user?

I don't think that you can do what you're trying to with a relation. I think that you'll need to model these relationships with a table:
{ fromUser, toUser, status }

Related

Get Student Submissions from Google Classroom

Goal: use Google App Script to get {link:url} and {driveFile:alternativeLink} from student submissions (attachments) to a Google Classroom Assignment.
Issue: While I can get all of the attachments, I cannot filter down to the specific type of attachment or it's respected property. Specific types of attachments return 'undefined'. Any help would be greatly appreciated.
I can get the the desired results using the Classroom API website by adding to the "field" input:
studentSubmissions.assignmentSubmission.attachments.driveFile
https://developers.google.com/classroom/reference/rest/v1/courses.courseWork.studentSubmissions/liststrong text
function testStudSubs(){
console.log(getStudSubs());
}
function getStudSubs(){
const COURSE_ID = "60005382479";
const COURSE_WORK_ID = "141252225149";
const USR_ID = {userId:"105308051639096321984"};
const ID = "Cg0IhMWczB0Q_dCnmo4E";
const submissions = Classroom.Courses.CourseWork.StudentSubmissions.list(COURSE_ID, COURSE_WORK_ID, USR_ID).studentSubmissions
return submissions.map(submission => {
return `${submission.assignmentSubmission.attachments}`
});
}
Answer: (Special thanks to Yagisanatode.com for pointing me in the correct direction.)
1st: ensure proper scopes have been added...see response from Sourabh Choraia stackOverflow response. The scopes will ensure we have access to the objects. Once we request a specific object (ex: link or driveFile), attachments that are not of that object type will display as undefined.
2nd: we need to remove the undefined objects. To do this, we can following w3resource (javascript version), adding the format to our "test" function (w3resource example).
We also need to tweak the array by flattening it. Flattening the array will show the correct length by including the undefined objects.
Finally, for the result, we will map it and pull the desired property (Google Api - Student Submissions List).
Here is working example:
function testStudSubs(){
console.log(getStudSubs());
console.log(getStudSubs().length);
console.log(getStudSubs().flat(2)); // creates separate object for each...ex: 4
const myFlat = getStudSubs().flat(2);
let index = -1;
const arr_length = myFlat ? myFlat.length : 0;
let resIndex = -1;
const result = [];
while (++index < arr_length) {
const value = myFlat[index];
if (value) {
result[++resIndex] = value;
}
}
console.log(result.map(result => { return result.alternateLink + `:` + result.title}));
return result.map(result => { return result.alternateLink + `:` + result.title});
}
/*/////////////////////////////
/
/ Pulls student submitted work from Classroom
/
*//////////////////////////////
function getStudSubs(){
const COURSE_ID = "60005382479"; // update
const COURSE_WORK_ID = "141252225149"; //update
const USR_ID = {userId:"105308051639096321984"}; //update
const submissions = Classroom.Courses.CourseWork.StudentSubmissions.list(COURSE_ID, COURSE_WORK_ID, USR_ID).studentSubmissions
return submissions.map(submission => {
return submission.assignmentSubmission.attachments.map(attachments =>
{
return attachments.driveFile
});
});
return submissions
}

Sequelize callback before save() is finished

here is my code:
//Models definition
var User = sequelize.define('user', ...);
var Address = sequelize.define('address', ...);
var Club = sequelize.define('club', ...);
//Club scopes
scopes: {
withUser: {
include: [
{ model: User }
]
},
//Models associations
User.hasOne(Address);
Club.hasOne(User);
Club.hasOne(Address);
//Main
//Create address
var addressToCreate = {};
if(body.address) addressToCreate.address = body.address;
if(body.city) addressToCreate.city = body.city;
if(body.zipCode) addressToCreate.zipCode = body.zipCode;
//Get user from db
var user = await User.findByPk(body.user);
var clubToCreate = { name: body.name, phone: body.phone };
//Persist Address in db
return Address.create(addressToCreate)
.then(address => {
//Persist club in db
return Club.create(clubToCreate)
.then(club => {
//Associate User and Address to Club
club.setAddress(address);
club.setUser(user);
//Save club with associated models
return club.save()
})
.then(club => Club.scope('withUser').findByPk(club.id))
.then(club => { console.log(club); return club; })
})
In my db, table address contains userId and clubId and table user contains clubId;
This code seems to work to create and associate models. But the final club displayed by console.log shows user: null
However, in db there is the good row in table user with the good foreign key who reference the club id
My logs show that the request select (from Club.findByPk) is done before the update (from club.save). Like .then is executed before promise is resolved
Sry for my bad english, hope someone can help
You are using async/await but mixing it up with the older promise style based on your code that fetches Users. Below is a copy of your code in async/await style, although you may not need to refetch the club object, etc, so continue to debug.
const address = await Address.create(addressToCreate);
let club = await Club.create(clubToCreate);
console.log('created club', club);
club.setAddress(address);
club.setUser(user);
await club.save();
console.log('saved club', club);
club = await Club.scope('withUser').findByPk(club.id);
console.log('reloaded club', club);
return club;

Laravel generate password and insert user in database by hand

I have few users with no email and password, and I would like to update users by adding email from freemail column, and setup password from random string.
This is my sample code:
public function updateUserProfil()
{
//find list user to be update(juste one to test)
$users = User::where('isfree', '1')->first();
//Random string generate
$motdepasse = str_random(6);
//find user
$updateUser= User::find($users->id);
//setup fields
$updateUser->email = $users->freemail;
$updateUser->remember_token = str_random(10);
$updateUser->motdepasse = $motdepasse;
$updateUser->password = bcrypt($motdepasse);
$updateUser->isfree = 0;
$updateUser->save();
}
The problem is that when I try to connect with email($users->freemail) and password($motdepasse), which is not encrypted random string, I get error that:
my credential is not valid
what did I miss ?
You can use update() to update rows. So your code must be
public function updateUserProfil()
{
//find list user to be update(juste one to test)
$users = User::where('isfree', '1')->first();
//Random string generate
$motdepasse = str_random(6);
//find user
$updateUser= User::find($users->id);
//setup fields
$updateUser->update([
'email'=>$users->freemail,
'remember_token'=>str_random(10),
'motdepasse'=>$motdepasse,
'password'=>bcrypt($motdepasse),
'isfree'=>0,
]);
}

Parse Cloud Right Query to retrieve Friendslist and not (like Instagram)

I have the class "Users" the default of Parse Dashboad. I have also the class "Friends", where I store the friendships between users like this:
There are two columns, "toUser" and "fromUser", which are showing who of the two users sent the friend request. These two columns are Pointers(Pointer<_User>) to the Users Class.
My concept is to retrieve two lists:
1. Friendlist for the logged in user
2. Userlist of users (who are not friends with the logged in user)
What would be the appropriate queries for that?
The first one logically should not scan all the class Users because it may slow down the perfomance of the app which is using Ionic 3 and Angular 4
Thank you
you don't need another class to do so all you need is a relation column in the default user class
to add new friend you just need the following code
var friendtoadd
//this is the friend object from parse user class you want to add you can get it by anyway you want
var currentUser = Parse.User.current();
var relation = currentUser.relation("friends");
relation.add(friendtoadd)
currentUser.save();
to retrieve array of friends of logged in user you can use the following code
var currentUser = Parse.User.current();
var friendRelation = currentUser.relation('friends');
var env = this
friendRelation.query().find({
success: function(users) {
for (var i = 0; i< users.length; i++) {
var object = users[i];
env.friends.push(object)
console.log(env.friends)
}
}
});
// you should define friends = []; in the class
if I understood your question right you want to find the friend requests you sent, or the ones you received. because I don't see where you made a relation between the user and his friends.
this is the code if you want to do this using cloud code:
First I validated the parameters of the friendRequest being saved :
Parse.Cloud.beforeSave("Friends", function(request, response){
var friendRequest = request.object;
if (!friendRequest.has("toUser") || !friendRequest.has("fromUser")) {
response.error("Invalid parameters");
return;
}
response.success();
});
then I created two cloud functions, one for retrieving the sentRequests:
Parse.Cloud.define("getSentRequests", function(request, response){
var query = new Parse.Query("Friends");
query.equalTo("fromUser", request.user);
if (!request.master) {
query.find({ sessionToken: request.user.getSessionToken() }).then(function(friends){
response.success(friends);
});
}else{
query.find({useMasterKey:true}).then(function(friends){
response.success(friends);
});
}
});
and you can call this either from a logged in user or using the masterKey if you want, and the other query is for the recievedRequests:
Parse.Cloud.define("getRecievedRequests", function(request, response){
var query = new Parse.Query("Friends");
query.equalTo("toUser", request.user);
if (!request.master) {
query.find({ sessionToken: request.user.getSessionToken() }).then(function(users){
response.success(users);
});
}else{
query.find({useMasterKey:true}).then(function(users){
response.success(users);
});
}
});

Find objects not in a relation

I have a custom object Team in Parse with a relation field for the default User object. What I would like to do is retrieve all User objects which are not related to any Team object. Can anyone point me in the right direction on how to do this using the JavaScript SDK? I've been going over the documentation for the Query object but I can't find anything.
Perhaps another type of relation, or placing the relation at another place is a better solution. What I want to accomplish is the following: Each user is allowed to be in one team and one team only. In addition I need to be able to query the following information from Parse:
I want to retrieve the User objects of all the users assigned to a team
I want to retrieve the User objects of all the users who are not assigned to any team
I have tried using a join table with both the user and team object ids. Then I tried to following query to get all users not assigned to a team:
var teammember = Parse.Object.extend('TeamMember'),
query = new Parse.Query("User");
var innerQuery = new Parse.Query("TeamMember");
query.doesNotMatchQuery('user', innerQuery);
query.find({
success: function(results) {
response.success(results);
},
error : function(error) {
response.error(error);
}
})
But this just gets me the following response: error: "{"code":102,"message":"bad type for $notInQuery"}".
I like the Relation type as I can add or remove multiple members at once with a single call to the REST API. I also have no problems retrieving the information on team members when using the Relation type to connect the users to the teams. It is just getting the users which are not assigned to any team that is giving me problems.
It doesn't sound like you need a relation at all. Instead, add a Pointer column to User that points to Team. It ensures that a User can only belong to one team, and your other requirements can be captured as follows.
// All users assigned to a team
query = new Parse.Query('User');
query.exists('team');
// All users assigned to a specific team
query = new Parse.Query('User');
query.equalTo('team', specificTeam);
// All unassigned users
query = new Parse.Query('User');
query.doesNotExist('team');
Update: If you need to support multiple teams per User in the future, then I would suggest creating a Parse table called Membership with two columns: a Pointer to User and a Pointer to Team. This essentially gives you more control than relying on Parse relations, but it gets a little more complicated.
_ = require('underscore'); // Or lodash
// All users assigned to a team
query = new Parse.Query('Membership');
query.find().then(function (results) {
// http://underscorejs.org/#uniq
users = _.uniq(results, false, function (user) { return user.id; });
});
// All users assigned to a specific team
query = new Parse.Query('Membership');
query.equalTo('team', specificTeam);
// All unassigned users
var assignedUsers = []
var unassignedUsers = []
memberQuery = new Parse.Query('Membership');
userQuery = new Parse.Query('User');
memberQuery.find().then(function (memberResults) {
// http://underscorejs.org/#map
var ids = _.map(memberResults, function (user) { return user.id; });
// http://underscore.js.org/#uniq
assignedUsers = _.uniq(ids);
userQuery.find();
}).then(function (userResults) {
var users = _.map(userResults, function (user) { return user.id; });
// http://underscorejs.org/#difference
unassignedUsers = _.difference(users, assignedUsers);
});
To add and remove Users to/from Teams, you would create Membership objects and save API calls with Parse.Object.saveAll() and Parse.Object.destroyAll().
I ran into trouble with the answer provided by Seth. When retrieving the users not assigned to a team the difference between the two arrays would be incorrect. I am assuming this is due to the assignedUsers having object of type Membership and userResults being of type User. This would make it impossible for underscore to make a proper match.
I would up using this as my Cloud Code:
Parse.Cloud.define("getTeamlessUsers", function(request, response) {
var _ = require("underscore"),
assignedUsers = [],
companyUsers = [],
memberQuery = new Parse.Query("TeamMembers"),
userQuery = new Parse.Query("User"),
index,
ubound;
memberQuery.find().then(function(memberResults) {
// Make sure each User ID will appear just once
memberResults = _.unique(memberResults, false, function(item) { return item.get('user').id; });
// Loop over the unique team members and push the User ID into the array
for (index = 0, ubound = memberResults.length; index < ubound; index++) {
var user = memberResults[index].get("user");
assignedUsers.push(user.id);
}
// Get al the users
return userQuery.find();
}).then(function(userResults) {
// Loop over all the users and push the ID into the array
for (index = 0, ubound = userResults.length; index < ubound; index++) {
companyUsers.push(userResults[index].id);
}
// Create an array of user IDs which are not present in the assignedUsers array
var result = _.difference(companyUsers, assignedUsers);
// Return the IDs of user not assigned to any team
response.success(result);
}).fail(function(error) {
response.error(error);
});
});

Resources