Connecting existing addEndpoint() to existing makeTarget() in jsPlumb - jsplumb

I have seen elsewhere the following technique for attaching existing endpoints. This works fine when both the source and target are created using addEndpoint()
var e0 = jsPlumb.addEndpoint("container0",{uuid:"ep1"}), //set your own uuid for endpoint for later access.
var e1 = jsPlumb.addEndpoint("container1",{uuid:"ep2"});
jsPlumb.connect({ uuids:[e1.getUuid(),e2.getUudi()] }); // (or) jsPlumb.connect({ uuids:["ep1","ep2"] });
However, in my case I need to join and endpoint to a target created using makeTarget()
var e0 = jsPlumb.addEndpoint("container0",{uuid:"ep1"}), //set your own uuid for endpoint for later access.
var e1 = jsPlumb.makeTarget("container1",{uuid:"ep2"});
jsPlumb.connect({ uuids:[e1.getUuid(),e2.getUudi()] }); // (or) jsPlumb.connect({ uuids:["ep1","ep2"] });
However this does not work and the returned results from makeTarget() does not even have a getUuid() method.
How can I achieve this?

This should work:
jsPlumb.connect({
source: sourceUUID,
target: targetID,
uuids: [sourceUUID, targetID],
editable: true
});

Related

beforeSave doesn't modify request.object

I'm trying to add some additional attributes for new user through cloud code:
Parse.Cloud.beforeSave(Parse.User, (request) => {
if (!request.original) {
// New user
Parse.Config.get()
.then((config) => {
const ProfileIcon = Parse.Object.extend("ProfileIcon");
const iconId = config.get("defaultProfileIcon");
const user = request.object;
// ...many user.set
user.set("profileIcon", ProfileIcon.createWithoutData(iconId), {
useMasterKey: true,
}); // Pointer
// This will save as expected, but cause recursion
// user.save({ useMasterKey: true });
})
.catch((err) => {
console.error(err);
});
}
});
The code above triggered and executed without any error, but when I check the database, none of my custom attributes show up. Passing the master key also does nothing. How can I fix this?
Or is it because the request from the client (Android, have no access to master key), if so then how can I set master key for the request, since Parse.Cloud.useMasterKey() is deprecated?
Here, modifying object on save does not mention anything about return, but before save file does. So I thought I would give it a try, turns out it worked. Still not sure if this is the right way though.

How to update an User with useMasterKey in Parse

Issue Description
I'm trying to update an User when another user click on my Xamarin button.
Then, I used Cloud Code to perform this but it doesnt work
My Code
Here is my complete JS code :
Parse.Cloud.beforeSave("Archive", function(request, response) {
Parse.serverURL = 'https://pg-app-0brffxkawi8lqvf2eyc2isqrs66zsu.scalabl.cloud/1/';
var status = request.object.get("status");
if (status == "validated") {
var event = request.object.get("event");
event.fetch({
success: function(myEvent) {
var coinsEvent = myEvent.get("coins");
var user = request.object.get("user");
user.fetch({
success: function(myUser, coinsEvent, user) {
var email = myUser.get("email");
var coinsUser = myUser.get("coins");
myUser.set("coins", coinsUser + coinsEvent);
return myUser.save(null, {useMasterKey:true});
}
});
}
});
}
response.success();
});
I think myUser.save(null, {useMasterKey:true}); should work
I actually have that error :
Dec 24, 2017, 12:27 GMT+1 - ERRORError generating response for [PUT] /1/classes/_User/1GPcqmn6Hd
"Cannot modify user 1GPcqmn6Hd."
{
"coins": 250
}
Environment Setup
Server
parse-server version : v2.3.3
Server: Sashido
Your success branch never calls response.success() which is a problem... though maybe not THE problem.
You are also doing 2 fetches inside a 'beforeSave' function which is not recommended. 'BeforeSave' must happen very quickly and fetches take time. I would consider thinking through other options.
If you really need to do it this way, consider doing a Parse.Query("event") with an include("user") and trigger the query with query.first({useMasterKey:true}).
Are you sure coinsEvent is what you think it is? Fetch only returns the object fetched... not sure that you can curry in other parameters. I would change your final success routine to (double checking that coinsEvent is valid):
success: function(myUser) {
var coinsUser = myUser.get("coins");
myUser.set("coins", coinsUser + coinsEvent);
return myUser.save(null, {useMasterKey:true}).then(_ => response.success());
}

Possible Parse bug in matchesKeyInQuery

If a post in my Parse database is liked, I want to send a push to the author via cloud code.
To be able to send pushes to specific users, all installations store the objectId of the current user. To find the author of the liked post, I use the query
var userWhosePostWasLikedQuery = new Parse.Query(Parse.Installation);
userWhosePostWasLikedQuery.equalTo(kClassInstallationKeyCurrentUserId, userWhosePostWasLiked.id);
This works fine: A single push is sent to the author.
Now I want to send this push only if the author has such pushes enabled. Thus each user stores a push settings array with enable flags for different pushes.
I use now another query for all users who have such pushes enabled:
const User = Parse.Object.extend(kClassUser);
var pushEnabledUserQuery = new Parse.Query(User);
pushEnabledUserQuery.equalTo(kClassUserKeyPushSettings, kPushNotificationTypePostLiked);
This query correctly returns all users who have such pushes enabled.
Eventually, I want to constrain the query for installations with the author as current user, by this query for users who have pushes enabled. This is done in the following way:
var userWhosePostWasLikedQuery = new Parse.Query(Parse.Installation);
userWhosePostWasLikedQuery.equalTo(kClassInstallationKeyCurrentUserId, userWhosePostWasLiked.id);
userWhosePostWasLikedQuery.matchesKeyInQuery(kClassInstallationKeyCurrentUserId, kPFObjectId, pushEnabledUserQuery);
Since the old query without the 3rd line returns 1 user, the new query with the additional constraint (matchesKeyInQuery) should return the same user, since the author has pushes enabled.
But it returns 2 users, the author and another user who liked the post.
To my understanding, this looks like a Parse bug, since all constraints to a query are ANDed.
Any ideas, maybe for a workaround?
your var "kPFObjectId" should be change to "user".
the default parse Installation come with the pointer named "user" and not "kPFObjectId".
I can tell you that Im using the same method ("matchesKeyInQuery") and it is working well:
Parse.Cloud.define("sendPushForChat", function(request, response) {
var userId = request.params.userId;
var groupId = request.params.groupId;
var query = new Parse.Query('RecentActivity');
query.equalTo('groupId',groupId);
query.include('user');
query.notEqualTo('user', {__type: "Pointer", className: "_User", objectId: userId});
var queryInstallation = new Parse.Query(Parse.Installation);
queryInstallation.matchesKeyInQuery('user', 'user', query);
var message = request.params.messageContent;
Parse.Push.send({
where: queryInstallation,
data: {
alert: message,
badge: "Increment",
title: "מה נשמע?"
}
}, {
success: function() {
console.log("Push for chat was successful");
response.success('Push for chat was successful');
},
error: function(error) {
console.error(error);
response.error('error');
},
useMasterKey:true,
});
})

Meteor call for sending image through api

Is it is possible to send image through meteor call to the API?
Client js
var r = {image : image};
Meteor.apply('callToServer', r, function(error, result){
console.log(result);
});
Server js
Meteor.methods({
uploadAndSaveToDB: function(data){
var result = Meteor.http.post(apiUrl, {
params: { image : data['image']}
});
var result = JSON.parse(result.content);
return result;
},
});
If your question is about how to get the image data and send it to your api, it depends on a couple factors:
How are you getting the image's data in the first place from your app (a submission form, a URL, some drawing library...)
In what format does the API you are calling expects the image data to be sent (URL, raw data, encrypted...)
If you are simply asking if it is doable, then yes, definitely. You will just need to add the http package for this:
meteor add http
You can then make requests to your api pretty much like you wrote it. Just make sure to give the right name to your method call (also use call and not apply if you are not submitting an array of arguments):
Client js
var r = {image : image};
Meteor.call('uploadAndSaveToDB', r, function(error, result){
console.log(result);
});
Server js
Meteor.methods({
uploadAndSaveToDB: function(data){
var result = HTTP.post(apiUrl, {
params: { image : data['image']}
});
var result = JSON.parse(result.content);
return result;
},
});

Using a query count inside an afterSave trigger (Parse.com cloud code)

I have a small afterSave trigger in my parse cloud code. The trigger just re-counts items that are flagged as deleted=false.
When I update my object, the count goes just fine, except when I update the deleted flag. It seems like the count is considering objects BEFORE the save event, which is not what I would expect from an "afterSave" trigger.
On the other hand, by using a "find" instead of a "count" on the very same query, I will always get the right number of objects. Of course the "find" way will go just when the query stays below 1000 objects.
Is there something wrong in my code? Is it the expected behavior? Is it a bug? Any alternative way to count objects the right way?
Thank you so much for your attention
Parse.Cloud.afterSave("BranchLike", function(request) {
console.log("Managing branchLike after save...");
Parse.Cloud.useMasterKey();
var branch = request.object.get("branch");
var branchLikeClass = Parse.Object.extend("BranchLike");
var type = request.object.get("type");
var branchLikeQuery = new Parse.Query(branchLikeClass);
branchLikeQuery.equalTo("branch",branch);
branchLikeQuery.equalTo("deleted",false);
branchLikeQuery.equalTo("type",type);
branchLikeQuery.count({
success: function(count) {
console.log("count = "+count); //works fine except on "delete" flag updates
/* ... */
},
error: function(error) {
/* ... */
}
});
branchLikeQuery.find({
success: function(branchLikes) {
console.log("ALTERNATIVE COUNT = "+branchLikes.length); //works fine when having less than 1000 objects
},
error: function(error) {
/* ... */
}
});
});

Resources