Add object with properties prefixed by underscore - firebase

I want to add objects on my Firebase database that contains properties prefixed by _.
It seems only these properties are ignored when saved.
My code looks like this and is working fine:
.config(function($provide) {
$provide.decorator('$firebaseArray', function($delegate, $window) {
var add, timestamp, currentUser;
add = $delegate.prototype.$add;
timestamp = $window.firebase.database.ServerValue.TIMESTAMP;
currentUser = $window.firebase.auth().currentUser.uid;
$delegate.prototype.$add = function (newData) {
//works if remove '_'
newData['_createdAt'] = timestamp;
newData['_createdBy'] = currentUser;
return add.call(this, newData);
};
return $delegate;
});
})
.config(function($provide) {
$provide.decorator('$firebaseObject', function($delegate, $window) {
var save, timestamp, currentUser;
save = $delegate.prototype.$save;
timestamp = $window.firebase.database.ServerValue.TIMESTAMP;
currentUser = $window.firebase.auth().currentUser.uid;
$delegate.prototype.$save = function () {
//works if remove '_'
this['_modifiedAt'] = timestamp;
this['_modifiedBy'] = currentUser;
return save.call(this);
};
return $delegate;
});
})

The reason this is ocurring is because AngularFire builtin method $firebaseUtils.toJSON removes some prefixed properties.
I solved my problem adding .toJSON() to my object model.
MyObject.prototype = {
toJSON: function () {
return angular.copy(this);
}
};

Related

Get the guid of the elements grouped in an ifcgroup

Is there a function in the API of IFCJS to get the guid of the elements grouped in an ifcgroup?
for example, if I group a column with a wall
getElementsFromIfcGroup(guidGroup) ---> return [guidWall, guidColumn]
According to the IFC schema, IfcGroup instances group elements together using an indirect relationship object called IfcRelAssignsToGroup. This means that you can retrieve the elements contained within that group like this:
import { IFCRELASSIGNSTOGROUP as REL } from 'web-ifc';
async function getItemsOfGroup(modelID, groupID) {
const manager = ifcLoader.ifcManager;
const relIDs = await manager.getAllItemsOfType(modelID, REL);
for(relID of groupsIDs) {
const groupRel = await manager.getItemProperties(modelID, relID);
if(groupRel.RelatingGroup.value === groupID) {
return groupRel.RelatedObjects;
}
}
return [];
}
based on Antonio's answer, it looks like this:
async function getItemsOfGroup(modelID, groupID) {
const manager = viewer.IFC.loader.ifcManager
// Get all ifcgroups
const relIDs = await manager.getAllItemsOfType(modelID, IFCRELASSIGNSTOGROUP);
let relID, relObj, props;
var guIDs = [];
for(relID of relIDs) {
const groupRel = await manager.getItemProperties(modelID, relID);
// Find the groupID
if(groupRel.GlobalId.value === groupID) {
// Search all related objects
for(relObj of groupRel.RelatedObjects) {
//get object properties
props = await manager.getItemProperties(modelID, relObj.value);
//Add guid to array
guIDs[guIDs.length] = props.GlobalId.value;
}
return guIDs;
}
}
return guIDs;
}

firebase .on value not returning null when no data exists

I'm using firebase in angular/ionic 2 and I need to check if a value exists and to create it if it doesn't however firebase is not returning null as it states in the docs and my check does not run because of it.
subscribeToOffer(uid, offerID) {
var path = 'users/' + uid + '/offers/' + offerID;
this.rootRef.child(path).on('value', subscribed => {
if (subscribed.val() !== null) {
console.log('subscribed');
} else {
console.log('not subscribed');
}
});
}
Here i have write a simple function for you that will return true if offer id exist and false in other case.
subscribeToOffer(userId,offerId){
var userRef = new Firebase(FBURL+'users');
var userOfferRef = userRef.child(userId).child("offers");
return userOfferRef.on("value", function(snap) {
var offerIds = snap.val();
return !!offerIds.hasOwnProperty(offerId);
});
};

Getting Ractive data by, say, "id", rather than by the object index

Say my Ractive data looks like this:
items: [
{ id: 16, name: "thingy" },
{ id: 23, name: "other thingy"}
]
I know I can do this to get the first item:
ractive.get('items.0')
But how do I get (or delete, or update, for that matter) the item who's id is 23?
Mostly a javascript issue, but you could put methods on your ractive instance or on the prototype generally. Assuming your array was not too large and using find and findIndex, you could do something like:
Ractive.prototype.getIndexById = function(keypath, id){
this.get(keypath).findIndex(function(each){
return each.id === id;
});
}
Ractive.prototype.getById = function(keypath, id){
return this.get(keypath).find(function(each){
return each.id === id;
});
}
Ractive.prototype.delete = function(keypath, id){
return this.splice(keypath, this.getIndexById(id), 1);
}
Ractive.prototype.update = function(keypath, id, data){
return this.set(keypath + '.' + this.getIndexById(id), data);
}
But if you're just trying to get a handle an item from which an action occurred, you should use the context:
{{#items:i}}
<li on-click='selected'>{{name}}</li>
<!-- or -->
<li on-click='selected(this, i)'>{{name}}</li>
{{/items}}
in your code
new Ractive({
...
selected: function(item, index){
// in lieu of passing in, you can access via this.event:
var item = this.event.context // current array member
var index = this.event.index.i // current index
},
oninit: function(){
this.on('selected', function(){
// same as method above
}
}
If you want to use jQuery, it can be done like this:
Ractive.prototype.getKeyById = function(keypath, id) {
var key;
key = -1;
$.each(this.get(keypath), function(i, data) {
if (data.id === id) {
key = i;
return false;
}
});
return key;
};

How can I get the name of the currently executing Meteor method?

Can I get the name of the currently executing Meteor method (from within
same)? This would be handy for logging.
I inspected this inside a Meteor method. It is an instance of MethodInvocation, and doesn't appear to have anything useful for figuring out the method name.
Seems like it would be easy enough to add the method name to MethodInvocation and callers, but I'm not sure if the maintainers would accept a patch that added a name field to every MethodInvocation instance.
Crossposted here.
It's not ideal, but here's how you could monkey-patch Meteor.methods to get this functionality, like stubailo suggests:
var currentMethod = new Meteor.EnvironmentVariable();
function log(message) {
var method = currentMethod.get();
if (method) {
console.log(method + ": " + message);
} else {
console.log(message);
}
}
var oldMeteorMethods = Meteor.methods;
Meteor.methods = function (object) {
var methods = {};
_.each(object, function (func, name) {
methods[name] = function () {
var self = this;
var args = _.toArray(arguments);
return currentMethod.withValue(name, function() {
return func.apply(self, args);
});
};
});
oldMeteorMethods(methods);
}
Meteor.methods({
example: function (arg1, arg2) {
log("hello");
return doSomethingElse(arg1) + arg2;
}
});
function doSomethingElse(x) {
log("doSomethingElse called with " + x);
return x * 2;
}
// Meteor.call("example", 5, 6) logs:
// "example: hello"
// "example: doSomethingElse called with 5"
If you prefer not to monkey-patch:
defineMethods = function (object) {
var methods = {};
_.each(object, function (func, name) {
methods[name] = function () {
var self = this;
var args = _.toArray(arguments);
return currentMethod.withValue(name, function() {
return func.apply(self, args);
});
};
});
Meteor.methods(methods);
}
defineMethods({
example: function (arg1, arg2) {
log("hello");
return doSomethingElse(arg1) + arg2;
}
});
It's easy with Meteor 1.10.1
You can just use
this.name
e.g
new ValidatedMethod({
name: "pod.create",
validate: new SimpleSchema({
stuff: {
type: String,
}
}).validator(),
run(pData) {
console.log("methodname:" + this.name);
}
});
outputs :
I20210126-08:35:30.120(0)? methodname:pod.create
I've reworked a little bit #user337's answer. Now you can use #name inside method function.
Add this to server code (coffeescript):
currentMethod = new Meteor.EnvironmentVariable()
oldMeteorMethods = Meteor.methods
Meteor.methods = (object) ->
methods = {}
_.each object, (func, name) ->
methods[name] = ->
args = _.toArray(arguments)
this.name = name
currentMethod.withValue name, =>
func.apply this, args
oldMeteorMethods methods
Just my two cents, for a fully working monkey patched version (without underscore).
Inside method function you can use this.currentMethodName now.
Meteor.methods = (object) => {
let methods = {};
let keys = Object.keys(object)
keys.forEach(key => {
methods[key] = function () {
let self = this;
let args = [...arguments];
self.currentMethodName = key
return object[key].apply(self, args);
}
})
oldMeteorMethods(methods);
}

JavaScript - passing variable from one function to another is undefined

in my example I'm trying to pass a variable (var ttoken) from one function to another and save it to the SQLite. The coding environment is Phonegap (for android). Here is the procedure:
var ttoken; // global var declaration
function handleLogin() {
var form = $("#loginForm");
var u = $("#username", form).val();
var p = $("#password", form).val();
if(u!= '' && p!= '') {
$.post("http://localhost/login.php", {username:u, password:p}, function(data){
if(data!='') {
$.mobile.changePage("change_page.html");
ttoken = data.token;
} else {
navigator.notification.alert("Error try again", function() {});
}
}, "json");
} else {
navigator.notification.alert("Error, fields are emty", function() {});
}
return {tkn:ttoken}; // putting into array
openDB();
populateDB();
}
var db;
function openDB(){ // create database
// 'Kurskoffer_DB' vol. 300 Kb
db = window.openDatabase("Sample_DB", "1.0", "Samole DB", 300000);
db.transaction(populateDB, errorCB, successCB);
}
function populateDB(tx){ // create 'settings' table
var tooken = handleLogin(); // accessing the variable ttoken
tx.executeSql('CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY, token TEXT NOT NULL, sound TEXT NOT NULL, vibra TEXT NOT NULL)');
tx.executeSql('INSERT INTO settings(id, token, sound, vibra) VALUES (1, "'+tooken.tkn+'", "on", "on")');
}
Seems everything according variable passing rule is ok, but the insert result in the table for field token is undefined. Have anyone idea why this is happening? Thanks.
The $.post function is asynchronous, which means handleLogin will return before the post callback has fired, and ttoken remains undefined in the returned object.
Set up handleLogin to accept a callback, which will fire when the post has returned and ttoken has been populated.
Something like:
function handleLogin(callback) {
var form = $("#loginForm");
var u = $("#username", form).val();
var p = $("#password", form).val();
if(u!= '' && p!= '') {
$.post("http://localhost/login.php", {username:u, password:p}, function(data){
if(data!='') {
$.mobile.changePage("change_page.html");
ttoken = data.token;
if (callback) callback();
} else {
navigator.notification.alert("Error try again", function() {});
}
}, "json");
} else {
navigator.notification.alert("Error, fields are emty", function() {});
}
}
function populateDB(tx){ // create 'settings' table
handleLogin(function() {
tx.executeSql('CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY, token TEXT NOT NULL, sound TEXT NOT NULL, vibra TEXT NOT NULL)');
tx.executeSql('INSERT INTO settings(id, token, sound, vibra) VALUES (1, "'+ttoken+'", "on", "on")');
});
}
Since ttoken is defined globally you don't have to worry about passing it around as an argument.

Resources