I have a collection of beacons that I want to show on a map. I want their positions to be synchronized between all instances of the application.
That is, when I move a beacons to another position I want this change to be reflected in the other instances of the application.
This using the Parse javascript SDK in its version 1.11.0.
I have defined the following Parse model, which represents each object in the collection saved on the server:
var Baliza = Parse.Object.extend("Balizas");
Baliza.prototype.show = function(){
var self = this;
var start= '<div class="row" style="width: 350px;">\n' +
' <div class="control-group" id="fields">\n' +
' <label class="control-label" style="text-align: center;" for="field1">Introducir Mac Asociadas a Ese Punto</label>\n' +
' <div class="controls">\n' +
' <form id="form" role="form" autocomplete="off">';
var tmp = '';
tmp = tmp + '<div class="entry input-group col-xs-12">\n' +
' <input class="form-control" name="fields[]" type="text" value="'+self.get("mac")[0]+'">\n' +
' <span class="input-group-btn">\n' +
' <button baliza-id='+self.id+' class="btn btn-success btn-add" type="button">\n' +
' <span class="glyphicon glyphicon-plus"></span>\n' +
' </button>\n' +
' </span>\n' +
' </div>';
if (self.get("mac").length>1){
for (var i=1; i<self.get("mac").length; i++) {
tmp = tmp + '<div class="entry input-group col-xs-12">\n' +
' <input class="form-control" name="fields[]" type="text" value="'+self.get("mac")[i]+'">\n' +
' <span class="input-group-btn">\n' +
' <button baliza-id='+self.id+' class="btn btn-remove col-xs-12" type="button">\n' +
' <span class="glyphicon glyphicon-minus"></span>\n' +
' </button>\n' +
' </span>\n' +
' </div>';
}
}
var end = '</form>\n' +
' <br>\n' +
' <button type="button" baliza-id='+self.id+' class="btn btn-block btn-info btn-sm ">Salvar</button>\n' +
' <button type="button" baliza-id='+self.id+' class="btn btn-block btn-danger btn-sm ">Eliminar</button>\n' +
' </div>\n' +
' </div>\n' +
'</div>';
//console.log('impirmiendo marker');
//console.log(this.marker);
console.log("Localización -> ", self.get("localizacion"));
if(self.marker != null) {
self.marker.setLatLng(new L.LatLng(self.get("localizacion").latitude, self.get("localizacion").longitude),{draggable:'true'});
} else {
self.marker = new L.marker([ self.get("localizacion").latitude, self.get("localizacion").longitude], {
icon: L.AwesomeMarkers.icon({icon: 'certificate', prefix: 'glyphicon', markerColor: 'blue'}),
draggable: 'true'
}).bindPopup("", {maxWidth: 560});
self.marker.on('dragend', function(event){
var position = event.target.getLatLng();
console.log("Notify new Location -> ", position.lat, position.lng);
//Enviamos El Dato a Parse
this.set("localizacion", new Parse.GeoPoint(position.lat, position.lng));
this.save(null, {
success: function (balizaSaved) {
console.log("Baliza Guardad con éxito: ", balizaSaved);
},
error: function (baliza, error) {
alert('Failed to create new object, with error code: ' + error.message);
}
});
}.bind(this));
map.addLayer(self.marker);
}
self.marker.getPopup().setContent(start+tmp+end);
};
The code responsible for notifying the change of position in the map is the following:
self.marker.on('dragend', function(event){
var position = event.target.getLatLng();
console.log("Notify new Location -> ", position.lat, position.lng);
//Enviamos El Dato a Parse
this.set("localizacion", new Parse.GeoPoint(position.lat, position.lng));
this.save(null, {
success: function (balizaSaved) {
console.log("Baliza Guardad con éxito: ", balizaSaved);
},
error: function (baliza, error) {
alert('Failed to create new object, with error code: ' + error.message);
}
});
}.bind(this));
The subscription was created as follows,
var query = new Parse.Query(Baliza);
var subscription = query.subscribe();
var mapaBalizasParse = new Map();
// After specifying the Monster subclass...
//Parse.Object.registerSubclass('Balizas',Baliza);
subscription.on('create', function (balizaCreated) {
console.log("New baliza created -> ", balizaCreated.toJSON());
var baliza = new Baliza(balizaCreated.toJSON());
baliza.show();
mapaBalizasParse.set(baliza.id, baliza);
});
subscription.on('update', function (balizaSaved) {
console.log('BALIZA ACTUALIZADA -> ', balizaSaved.toJSON());
var baliza = mapaBalizasParse.get(balizaSaved.id);
baliza.set("mac", balizaSaved.get("mac"));
baliza.set("localizacion", balizaSaved.get("localizacion"));
baliza.show();
});
subscription.on('delete', function (baliza) {
//console.log(mapaBalizasParse.get(baliza.id));
map.removeLayer(mapaBalizasParse.get(baliza.id).marker);
mapaBalizasParse.delete(baliza.id);
});
subscription.on('leave', function (balizaLeave) {
console.log('Leave called -> ', balizaLeave.id, balizaLeave.get("localizacion"));
});
subscription.on('enter', function (balizaCalled) {
console.log('Enter called -> ', balizaCalled.id, balizaCalled.get("localizacion"));
});
Each time I click on a position on the map I create a Beacons as follows:
function onMapClick(e) {
var baliza = new Baliza();
baliza.set("localizacion",new Parse.GeoPoint(e.latlng.lat, e.latlng.lng));
baliza.set("mac",["11:22:33:44:55:10"]);
baliza.set("editando",true);
baliza.save(null, {
success: function(baliza) {
//Añadimos La Baliza Al Mapa Interno
//mapaBalizasParse.set(baliza.id,baliza);
//baliza.show();
},
error: function(baliza, error) {
alert('Failed to create new object, with error code: ' + error.message);
}
});
}
The list of currently registered "beacons" is shown as follows:
query.find({
success: function(results) {
console.log("Total Balizas -> " + results.length);
for (var i = 0; i < results.length; i++) {
var currentBaliza = results[i];
console.log("Baliza " + i + " -> ", currentBaliza);
currentBaliza.show();
mapaBalizasParse.set(currentBaliza.id, currentBaliza);
}
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
The problem is if for example I move the beacon from position ( latitude: 40.961229844235234, longitude: -5.669621229171753 ) to another point in the map (latitude: 40.9604196476232, longitude: -5.6707102060318)
The other instances of the application receive in the update event the old version of the object, its location field has not changed ( latitude: 40.961229844235234, longitude: -5.669621229171753 )
Someone can tell me what I'm doing wrong in the code.
Thanks in advance.
I have been doing some test with minimal configuration and this is that I saw:
In the callback for loading all beacons in the map set you use this code:
but when you add a new beacon created in the callback of 'create' event, you use this one:
In my tests, if you use the first code the beacons updates normally, but if you use the second one, a old version of the beacon is logged in javascript console.
It seems that something special happens in the empty constructor that you are not including in the overloaded constructor.
I hope that it helps you. :)
Here my complete code:
HTML
JS