Existing ForerunnerDB database cleared after new ForerunnerDB() command - forerunnerdb

Cannot get ForerunnerDB to load existing data. Upon browser refresh, entire IndexedDB database disappears from Chrome resources after executing new ForeRunnerDB() command.
var fdb = new ForerunnerDB();
// Existing database disappears from Chrome resources here
var db = fdb.db('VRC');
db.collection('videos').load();
var videoCollection = db.collection('videos');
if (!videoCollection.count()) {
videoCollection.setData([
{
"_id": 1,
"name": "Joe"
},
{
"_id": 2,
"name": "Susan"
}]);
// Yeah, I know this is redundant...
videoCollection.save();
db.save();
ForerunnerDB.save();
}

Problem was solved by passing a function to Collection.load():
videoCollection.load(function() {
// Do something with data here
});

Related

FORM.IO - Render/Re-build from a variable

I'm doing some tests with https://unpkg.com/formiojs#latest/dist/formio.full.min.js
I was able to integrate the constructor in my application and save the generated JSON in a table.
Now I want to bring that JSON and be able to edit or render the form but I'm not doing something right.
This is my code:
window.onload = function () {
var jsonForm1 = document.getElementById ("value_forn_1"). value;
console.log (jsonForm1);
var builder = new Formio.builder (document.getElementById ("edit"), jsonForm1, {});
builder.then (function (form) {
form.on ("change", function (e) {
console.log ("builder");
var jsonSchema = JSON.stringify (form.schema, null, 4);
console.log (jsonSchema);
$ ("# value_forn_1"). val (jsonSchema);
});
});
};
value_forn_1 is the textarea containing the JSON retrieved from my table
the console.log (jsonForm1) shows me the JSON of the textarea by console
But if I want to pass the variable jsonForm1 from inside Formio.builder, I get the error:
Uncaught TypeError: Cannot read properties of null (reading '1')
4)On the other hand, if I directly assign the JSON to jsonForm1:
var jsonForm1 = { "components": [ { "label": "Text Field", "tableView": true, "key": "textField", "type": "textfield", "input": true }, { "label": "Text Area", "autoExpand": false, "tableView": true, "key": "textArea", "type": "textarea", "input": true } ] };
The rendering works ....
What am I doing wrong?
I think you already answered your own question but the schema in the jsonForm1 variable should be parsed into a JSON object to be passed into the Formio.builder function.
var jsonForm1 = JSON.parse(document.getElementById ("value_forn_1").value);
Additionally you can check out their sandbox. It's been very helpful working with the js library.
Sandbox:
https://formio.github.io/formio.js/app/sandbox
Code behind the sandbox (see initRenderer function):
https://github.com/formio/formio.js/blob/master/app/sandbox.html

How to update me endpoint in Strapi?

Im working with Strapi v3.4.0 for a project. I want to allow the authenticated user to update his personal informations when hitting the following endpoint:
PUT /users/me
for now I'm just trying to console.log a message when i hit the endpoint, I have followed the step from this video: https://www.youtube.com/watch?v=ITk-pYtOCnQ but I keep getting 403 error "Forbidden". Am I doing something wrong?
I understand this update me problem in Strapi is really painful. I have also followed the tutorial on the link you put above to no avail since Strapi just updated to the new version. I tried a workaround for this solution. So basically, I tried to create an additional method on the model that shows on the api folder (Previously, I am trying to add a new method on user controller but again I got this 403 error as well). As for my approach, I created a model called User Profile and then add the custom method for updating the current user data shown below.
api/user-profile/config/routes.json
...
{
"method": "PUT",
"path": "/updateMe",
"handler": "user-profile.updateMe",
"config": {
"policies": []
}
},
{
"method": "PUT",
"path": "/user-profiles/:id",
"handler": "user-profile.update",
"config": {
"policies": []
}
}
...
and on the controller, I added the following snippets
api/user-profile/controllers/user-profile.js
'use strict';
const _ = require('lodash');
const { sanitizeEntity } = require('strapi-utils');
const sanitizeUser = user =>
sanitizeEntity(user, {
model: strapi.query('user', 'users-permissions').model,
});
const formatError = error => [
{ messages: [{ id: error.id, message: error.message, field: error.field }] },
];
module.exports = {
async updateMe(ctx) {
const { id } = ctx.state.user;
let updateData = {
...ctx.request.body,
};
const data = await strapi.plugins['users-permissions'].services.user.edit({ id }, updateData);
ctx.send(sanitizeUser(data));
},
};
After that, enable the updateMe for the public use (for now, you do not have to worry since the ctx.state.user line will check if the token is valid or not, { at least until the developer officially create this updateMe function })
That is all. You just have to pass the attributes to the body and the auth header and you are good to go. You can pretty much put the function anywhere you want
PS: Take a note that you have to put the updateMe route above the update route. Else, it will give you the same 403 error
PPS: This is just a workaround until the developer officially includes the updateMe function, which we cannot expect in short time

Mongoose - can't insert subDocuments of a Dictionary Type

I have a Mongoose schema for the document Company, that has several fields. One of these (documents_banks) is a "free" field, of dictionary type, because I don't know the names of the keys in advance.
The problem is that, when I save the document (company.save()) even if the resulting saved document has the new sub_docs, in the DB no new sub_docs are actually saved.
var Company = new Schema({
banks: [{ type: String }], // array of Strings
documents_banks: {} // free field
});
Even if documents_banks is not restricted by the Schema, it will have this structure (in my mind):
{
"bank_id1": {
"doc_type1": {
"url": { "type": "String" },
"custom_name": { "type": "String" }
},
"doc_type2": {
"url": { "type": "String" },
"custom_name": { "type": "String" }
}
},
"bank_id2": {
"doc_type1": {
"url": { "type": "String" },
"custom_name": { "type": "String" }
}
}
}
But I don't know in advance names of keys bank_id neither doc_type, so I used the Dictionary type (documents_banks:{}).
Now, this below is the function I use to save new sub_docs in documents_banks. The same logic I always use to save new sub_docs.. Anyway this time, it seems saved, but it's not.
function addBankDocument(company_id, bank_id, doc_type, url, custom_name) {
// retrieve the company document
Company.findById(company_id)
.then(function(company) {
// create empty sub_docs if needed
if (!company.documents_banks) {
company.documents_banks = {};
}
if (!company.documents_banks[bank_id]) {
company.documents_banks[bank_id] = {};
}
// add the new sub_doc
company.documents_bank[bank_id][doc_type] = {
"url": url,
"custom_name": custom_name
};
return company.save();
})
.then(function(saved_company) {
// I try to check if the new obj has been saved
console.log(saved_company.documents_bank[bank_id][doc_type]);
// and it actually prints the new obj!!
});
}
The saved_company returned by the .save() actually has the new sub_docs, but if I check the DB there is not the new sub_doc! I can save just the first one, all the others are not stored.
So, the console.log() always print the new sub_docs, but actually in the DataBase, just the first sub_doc is saved, not the others. So at the end, saved_company always has 1 sub_doc, the first one.
It seems very strange to me, since saved_company has the new sub_docs. What can be happened?
This below is a real extract from by DB, and it will contains forever just the sub_doc "doc_bank#1573807781414", others will be not present in the DB.
{
"_id": "5c6eaf8efdc21500146e289c", // company_id
"banks": [ "MPS" ],
"documents_banks": {
"5c5ac3e025acd98596021a9a": // bank_id
{
"doc_bank#1573807781414": // doc_type
{
"url": "http://...",
"custom_name": "file1"
}
}
}
}
Versions:
$ npm -v
6.4.1
$ npm show mongoose version
5.7.11
$ node -v
v8.16.0
It seems that, since mongoose doesn't know the exact model of the subdoc, it can't know when it changes. So I have to use markModified to notify changes of the "free field" (also known as dictionary or MixedType) with this:
company_doc.documents_banks["bank_id2"]["doc_type3"] = obj; // modify
company_doc.markModified('documents_banks'); // <--- notify changes
company_doc.save(); // save changes
As I understood, markModified force the model to 'update' that field during the save().

mongo forEach unable to update array in document

I'm trying write a mongo script to run in RoboMongo that will loop through all documents in a collection. Each document contains an array myArray. The documents look like this:
{
"name": "myApp",
"myArray": [
{ "env": "dev", "dbHost": "db2dev.local" },
{ "env": "prod", "dbHost": "db1prod.local" }
]
I want to copy the dbHost field that is defined in dev to prod. So the above result would be:
{
"name": "myApp",
"myArray": [
{ "env": "dev", "dbHost": "db2dev.local" },
{ "env": "prod", "dbHost": "db2dev.local" }
]
When I try to access the field myArray[0] I get a syntax error that says:
TypeError: myDoc.myArray[0] is undefined
The function is something like this:
db.myCollection.find().forEach( function(myDoc) {
var devIdx = 0;
var prodIdx = 1;
if (myDoc.myArray[0].env !== 'dev')}
devIdx = 1;
prodIdx = 0;
}
myDoc.myArray[prodIdx].dbHost = myDoc.myArray[devIdx].dbHost;
print(myDoc);
});
I've examined the collection (it is very small) and each document has a myArray field as it should with exactly two values (one for dev and one for prod) in the array.
What am I doing wrong? What is the correct syntax to use inside a mongo script? Is updating arrays in a document not supported?
Searching for solution
I've searched and found forEach examples but most are trivial and none include an array being accessed or changed.
The mongo docs are also very simplistic: https://docs.mongodb.com/v3.6/reference/method/cursor.forEach/
Mongo javascript does not allow you to access arrays directly like you are trying to do (unless you are in a for loop). So a solution is shown below:
db.myCollection.find({}).forEach( function(myDoc) {
var foundDevEntry = null;
var updatedProdEntry = false;
// First time loop to get a copy of the dev entry
for (var idx in myDoc.myArray) {
if (myDoc.myArray[idx].env === 'dev') {
foundDevEntry = myDoc.myArray[idx];
}
}
// 2nd time loop to update the value
for (var idx in myDoc.myArray) {
if (myDoc.myArray[idx].env === 'prod') {
myDoc.myArray[idx].dbHost = foundDevEntry.dbHost;
}
}
// Now update the database with this change
db.myCollection.update({_id: myDoc._id}, {$set: {"myArray": myDoc.myArray}});
print(myDoc); // So results are also returned when query is run
});
I've stripped out error checking to focus on the change required. What (to me) is odd is that the syntax myDoc.myArray[idx] is actually valid but only inside a loop!
The following references helped me come to a solution:
Update in forEach on mongodb shell
https://www.mysoftkey.com/mongodb/how-to-use-foreach-loop-in-mongodb-to-manipulate-document/
I should add that some solutions I read said that to update an array you had to re-build the array (https://stackoverflow.com/a/22657219/3281336). I did not do that in my solution and it did work but wanted to share it.

changed object structure from item with object to array of objects in MongoDB shows error "An error occurred while deserializing"

I have changed the object structure from
{
id:"...",
name:"...",
url:"...",
studentAccess:{
"A":"....",
"B":"...",
},
ecosystemId:"..."
}
TO:
{
id:"...",
name:"...",
url:"...",
studentAccess:[
{
"X":"....",
"Y":"..."
},
{
"X":"....",
"Y":"..."
},
{
"X":"....",
"Y":"..."
},
],
ecosystemId:"..."
}
in API we get list of these objects based on ecosystemid or student access item "X", name or any field..calling like this in API
var acc = await _eco.FindByUser();
var query = await _db.CourseDocuments.FindAsync(w => w.EcosystemId == acc.Identifier);
after query executes i get this error pls help me i need to change structure anywhere after it changed in mongoDB?