Modify runtime collection with a template metada collection
D
Dany Savard
started a topic
over 6 years ago
Hi!
I tried to modify a runtime collection from a metadata collection. I explain:
When a player is created, I use the "template" meta collection to build a runtime collection for default values. But, I want to keep the player runtime collection updated with the template meta collection when I add/remove fields. So, I use a field "VERSION" to detect when a new version is available.
The update function:
function UpdateCollection(runtimeCol, metaCol)
{
var playerID = Spark.getPlayer().getPlayerId();
var updateObject = {};
//add new keys
for(var metaKey in metaCol)
{
if(metaKey != "_id")
{
var found = false;
for(var runKey in runtimeCol)
{
if(runKey == metaKey)
{
found = true;
break;
}
}
if( !found)
{
updateObject[metaKey] = metaCol[metaKey];
}
}
}
runtimeCol.update({"playerID": playerID }, {"$set" : updateObject}, true, false);
Spark.setScriptData(collName, runtimeCol);
}
But I have a error when I tried to update the runtime collection at line:
The error is: TypeError: Cannot find default value for object. (296145-event-GetRuntimeCollection#69)
I have no experience with NoSQL, I am poor in javascript so, don't be too rude!
Where is my error ?
Thanks!
Best Answer
C
Christian Gauthier
said
over 6 years ago
Dany,
metaCol and runtimeColl parameters are objects of type SparkMongoCollectionReadWrite that you surely obtain using Sparks.runtimeCollection("TheNameOfYourCollection")). You use them to do your CRUD operations.
In your case you want to query the collection so your have to call find() with search parameters like a SELECT FROM WHERE in sql.
//first get your template document, I presume you dont really have one template per player like your code seems to do, because
//having a template document for each of the players will defeat the concept of template, may be I'm wrong
//I also presume that you have something uniquely identifying your template, i use a "code" property that has a value of DEFAULT
var template = metaCol.findOne({"code": "DEFAULT");
//Again, I presume that you have a runtime collection that has a document (row) for every players in the system with a property named "playerID"
//maybe you decided to use "setScriptData" on the player in that case you would not do the following:
var playerData = runtimeCol.find({"playerID": playerID});
//now you have 2 javascript objects that you can manipulate like any js objects
//go through all the properties of the template objects and assign the values to playerData
for (var prop in template) {
if (template.hasOwnProperty(prop)) {
playerData[prop] = template[prop];
}
}
//you can use update
runtimeCol.update({"playerID": playerID }, playerData, false, false);
//or save
runtimeCol.save(playerData);
metaCol and runtimeColl parameters are objects of type SparkMongoCollectionReadWrite that you surely obtain using Sparks.runtimeCollection("TheNameOfYourCollection")). You use them to do your CRUD operations.
In your case you want to query the collection so your have to call find() with search parameters like a SELECT FROM WHERE in sql.
//first get your template document, I presume you dont really have one template per player like your code seems to do, because
//having a template document for each of the players will defeat the concept of template, may be I'm wrong
//I also presume that you have something uniquely identifying your template, i use a "code" property that has a value of DEFAULT
var template = metaCol.findOne({"code": "DEFAULT");
//Again, I presume that you have a runtime collection that has a document (row) for every players in the system with a property named "playerID"
//maybe you decided to use "setScriptData" on the player in that case you would not do the following:
var playerData = runtimeCol.find({"playerID": playerID});
//now you have 2 javascript objects that you can manipulate like any js objects
//go through all the properties of the template objects and assign the values to playerData
for (var prop in template) {
if (template.hasOwnProperty(prop)) {
playerData[prop] = template[prop];
}
}
//you can use update
runtimeCol.update({"playerID": playerID }, playerData, false, false);
//or save
runtimeCol.save(playerData);
D
Dany Savard
said
over 6 years ago
Thanks Christian!
D
Dany Savard
said
over 6 years ago
Just one more question and it is related to Javascript.
It exists a function to know if a JS object has a field other than iterate on all fields and verify if the key is present? By example this (the solution for my first question), the code below. This code works but, you know, a "Contains" function should be sexier!
var runtimeCol = Spark.runtimeCollection(collName).findOne({"playerID": Spark.getPlayer().getPlayerId()});
var metaCol = Spark.metaCollection(collName).findOne({"_id" : idValue});
var playerID = Spark.getPlayer().getPlayerId();
var newValues = {};
var removedValues = {};
for(var metaKey in metaCol)
{
if(metaKey != "_id")
{
var found = false;
for(var runKey in runtimeCol)
{
if(runKey == metaKey)
{
found = true;
break;
}
}
if( !found)
{
//add new keys in runtime from meta collection
newValues[metaKey] = metaCol[metaKey];
}
}
}
for(var runKey in runtimeCol)
{
if(runKey != "_id" && runKey != "playerID")
{
var found = false;
for(var metaKey in metaCol)
{
if(runKey == metaKey)
{
found = true;
break;
}
}
if( !found)
{
//remove keys in runtime collection but no more in meta collection
removedValues[runKey] = runtimeCol[runKey];
}
}
}
//update version
newValues["VERSION"] = metaCol["VERSION"];
runtimeCol = Spark.runtimeCollection(collName);
if(Object.keys(newValues).length > 0 )
runtimeCol.update({"playerID": playerID }, {"$set" : newValues}, true, false);
if(Object.keys(removedValues).length > 0 )
runtimeCol.update({"playerID": playerID }, {"$unset" : removedValues}, true, false);
Spark.setScriptData(collName, runtimeCol);
}
D
Dany Savard
said
over 6 years ago
Ok, I figured out how to do like a "Contains" function with JS array functions.
This post is a few months old, but I had to do a similar concept, so wanted to post my final code, in hopes it will help someone in the future. It uses a similar code to Dany, but also allows you to create a new set of stats, if the user is new. It also only returns the stats themselves, and not the other Collection info.
Dany Savard
Hi!
I tried to modify a runtime collection from a metadata collection. I explain:
When a player is created, I use the "template" meta collection to build a runtime collection for default values. But, I want to keep the player runtime collection updated with the template meta collection when I add/remove fields. So, I use a field "VERSION" to detect when a new version is available.
The update function:
But I have a error when I tried to update the runtime collection at line:
runtimeCol.update({"playerID": playerID }, {"$set" : updateObject}, true, false);
The error is: TypeError: Cannot find default value for object. (296145-event-GetRuntimeCollection#69)
I have no experience with NoSQL, I am poor in javascript so, don't be too rude!
Where is my error ?
Thanks!
Dany,
metaCol and runtimeColl parameters are objects of type SparkMongoCollectionReadWrite that you surely obtain using Sparks.runtimeCollection("TheNameOfYourCollection")). You use them to do your CRUD operations.
In your case you want to query the collection so your have to call find() with search parameters like a SELECT FROM WHERE in sql.
You can have more info here
But here what I would have done:
- Oldest First
- Popular
- Newest First
Sorted by Oldest FirstChristian Gauthier
Dany,
metaCol and runtimeColl parameters are objects of type SparkMongoCollectionReadWrite that you surely obtain using Sparks.runtimeCollection("TheNameOfYourCollection")). You use them to do your CRUD operations.
In your case you want to query the collection so your have to call find() with search parameters like a SELECT FROM WHERE in sql.
You can have more info here
But here what I would have done:
Dany Savard
Thanks Christian!
Dany Savard
Just one more question and it is related to Javascript.
It exists a function to know if a JS object has a field other than iterate on all fields and verify if the key is present? By example this (the solution for my first question), the code below. This code works but, you know, a "Contains" function should be sexier!
Dany Savard
Ok, I figured out how to do like a "Contains" function with JS array functions.
Thanks.
Brett Unzaga
This post is a few months old, but I had to do a similar concept, so wanted to post my final code, in hopes it will help someone in the future. It uses a similar code to Dany, but also allows you to create a new set of stats, if the user is new. It also only returns the stats themselves, and not the other Collection info.
-
Documentation Notes
-
Design issues with user events
-
Using NoSQL
-
Runtime Collections vs Metadata Collections
-
Anonymous authentication from browser app
-
Modules
-
Movement With Unity
-
Problem with url parameters for downloadables
-
Querying NoSql GameSparks database
-
Challenge accesType
See all 2487 topics