Ramda `evolve` nested object - ramda.js

I have a list similar to this:
var list = [
{
stack: [
{
file: 'abc'
}
]
},
{
stack: [
{
file: 'abc'
},
{
file: 'abc'
}
]
}
];
I want to change every file name with e.g 'def'. How to do that by using ramda ?
I tried things like:
var trans = {
file: replace('abc', 'def')
};
var f = R.evolve(trans)
var f2 = R.map(f)
R.map(f2, list)
But it doesn't work. I need to include stack field in solution somehow.

Well, it's not pretty, but I think this will do it:
R.map(R.over(
R.lensProp('stack'),
R.map(R.over(R.lensProp('file'), R.replace('abc', 'def')))
))(list)
You could probably also use an evolve inside, but lenses are pretty powerful, and more generally useful.

Related

Set programmatically jsonValidation for dynamic mapping

I am creating a new vscode extension, and I need to extend the standard usage of the jsonValidation system already present in vscode.
Note : I am talking about the system defined in package.json :
"contributes" : {
"languages": [
{
"id" : "yml",
"filenamePatterns": ["module.service"]
},
{
"id" : "json",
"filenamePatterns": ["module.*"]
}
],
"jsonValidation": [
{
"fileMatch": "module.test",
"url": "./resources/test.schema"
}
]
}
Now, I need to create a dynamic mapping, where the json fields filematch/url are defined from some internal rules (like version and other internal stuff). The standard usage is static : one fileMatch -> one schema.
I want for example to read the version from the json file to validate, and set the schema after that :
{
"version" : "1.1"
}
validation schema must be test-schema.1.1 instead of test-schema.1.0
note : The question is only about the modification of the configuration provided by package.json from the extensions.ts
Thanks for the support
** EDIT since the previous solution was not working in all cases
There is one solution to modify the package.json at the activating of the function.
export function activate(context: vscode.ExtensionContext) {
const myPlugin = vscode.extensions.getExtension("your.plugin.id");
if (!myPlugin)
{
throw new Error("Composer plugin is not found...")
}
// Get the current workspace path to found the schema later.
const folderPath = vscode.workspace.workspaceFolders;
if (!folderPath)
{
return;
}
const baseUri : vscode.Uri = folderPath[0].uri;
let packageJSON = myPlugin.packageJSON;
if (packageJSON && packageJSON.contributes && packageJSON.contributes.jsonValidation)
{
let jsonValidation = packageJSON.contributes.jsonValidation;
const schemaUri : vscode.Uri = vscode.Uri.joinPath(baseUri, "/schema/value-0.3.0.json-schema");
const schema = new JsonSchemaMatch("value.ospp", schemaUri)
jsonValidation.push(schema);
}
}
And the json schema class
class JsonSchemaMatch
{
fileMatch: string;
url : string;
constructor(fileMatch : string, url: vscode.Uri)
{
this.fileMatch = fileMatch;
this.url = url.path;
}
}
Another important information is the loading of the element of contributes is not reread after modification, for example
class Language
{
id: string;
filenamePatterns : string[];
constructor(id : string, filenamePatterns: string[])
{
this.id = id;
this.filenamePatterns = filenamePatterns;
}
}
if (packageJSON && packageJSON.contributes && packageJSON.contributes.languages)
{
let languages : Language[] = packageJSON.contributes.languages;
for (let language of languages) {
if (language.id == "json") {
language.filenamePatterns.push("test.my-json-type")
}
}
}
This change has no effect, since the loading of file association is already done (I have not dig for the reason, but I think this is the case)
In this case, creating a settings.json in the workspace directory can do the job:
settings.json
{
"files.associations": {
"target.snmp": "json",
"stack.cfg": "json"
}
}
Be aware that the settings.json can be created by the user with legitimate reason, so don't override it, just fill it.

Why is Date query with aggregate is not working in parse-server?

I want to query user where updatedAt is less than or equal today using aggregate because I'm doing other stuff like sorting by pointers.
I'm using cloud code to define the query from the server.
I first tried using mongoDB Compass to check my query using ISODate and it works, but using it in NodeJS seems not working correctly.
I also noticed about this problem that was already fix, they say. I also saw their tests.
Here's a link to that PR.
I'm passing date like this:
const pipeline = [
{
project: {
_id: true,
process: {
$substr: ['$_p_testdata', 12, -1]
}
}
},
{
lookup: {
from: 'Test',
localField: 'process',
foreignField: '_id',
as: 'process'
}
},
{
unwind: {
path: '$process'
}
},
{
match: {
'process._updated_at': {
$lte: new Date()
}
}
}
];
const query = new Parse.Query('data');
return query.aggregate(pipeline);
I expect value to be an array with length of 4 but only give me empty array.
I was able to fetch data without match date.
Please try this:
const pipeline = [
{
match: {
'editedBy.updatedAt': {
$lte: new Date()
}
}
}
];

Add a new element in each array of objects where array may have different length in mongodb

I have a following shema.
{
id:week
output:{
headerValues:[
{startDate:"0707",headers:"ID|week"},
{startDate:"0715",headers:"ID1|week1"},
{startDate:"0722",headers:"ID2|week2"}
]
}
}
I have to add a new field into headerValues array like this:
{
id:week
output:{
headerValues[
{startDate:"0707",headers:"ID|week",types:"used"},
{startDate:"0715",headers:"ID1|week1",types:"used"},
{startDate:"0722",headers:"ID2|week2",types:"used"}
]
}
}
I tried different approaches like this:
1)
db.CollectionName.find({}).forEach(function(data){
for(var i=0;i<data.output.headerValues.length;i++) {
db.CollectionName.update({
"_id": data._id, "output.headerValues.startDate":data.output.headerValues[i].startDate
},
{
"$set": {
"output.headerValues.$.types":"used"
}
},true,true
);
}
})
So, In this approach it is executing script and then failing. It is updating result with failed statement.
2)
Another approach I have followed using this link:
https://jira.mongodb.org/browse/SERVER-1243
db.collectionName.update({"_id":"week"},
{ "$set": { "output.headerValues.$[].types":"used" }
})
But it fails with error:
cannot use the part (headerValues of output.headerValues.$[].types) to
traverse the element ({headerValues: [ { startDate: "0707", headers:
"Id|week" } ]}) WriteError#src/mongo/shell/bulk_api.js:469:48
Bulk/mergeBatchResults#src/mongo/shell/bulk_api.js:836:49
Bulk/executeBatch#src/mongo/shell/bulk_api.js:906:13
Bulk/this.execute#src/mongo/shell/bulk_api.js:1150:21
DBCollection.prototype.updateOne#src/mongo/shell/crud_api.js:550:17
#(shell):1:1
I have searched with many different ways which can update different arrays object by adding new field to each object but no success. Can anybody please suggest that what am I doing wrong?
Your query is {"_id" : "week"} but in your data id field is week
So you can change {"_id" : "week"} to {"id" : "week"} and also update your mongodb latest version
db.collectionName.update({"id":"week"},
{ "$set": { "output.headerValues.$[].types":"used" }
})

Lodash differenceBy alternative

I am trying to find a way to differentiate between 2 object literals by a property from each.
I can get this working by using 2 ._forEach()
_.forEach(forms, form => {
_.forEach(this.sections, section => {
if(form.section === section.name){
section.inProgress = true;
}
});
});
However this does not seem ideal. I have tried with the _.differenceBy
_.differenceBy(forms, this.sections, 'x');
But I cant differentiate by the property name as the "name" that i want to check by is name in one of the arrays and section in the other.
I want to use something like
_.differenceBy(forms, this.sections, 'section' === 'name');
It there something in lodash for this?
You can use _.differenceWith() with a comparator that refers to a specified object property in each array:
var forms = [{ 'name': 'somethingA' }, { 'name': 'somethingB' }];
var sections = [{ section: 'somethingB' }];
var result = _.differenceWith(forms, sections, function(arrValue, othValue) {
return arrValue.name === othValue.section;
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Nesting components with mithril.js

I'm trying to put together some nested components to assemble a larger page.
The use of the interim steps to create the view seems like an overkill, but this is only one part of many more components that will be put together. Beside that it gives a good overview what is happening. But I don't get it right without errors.
Here is a code example
var MyApp = {
controller: function() {
return {loaded: true}
},
view: function(ctrl) {
return //[ // remove comment for var1
m("button[type=button]", {onclick: function() {ctrl.loaded = false}})
, ctrl.loaded ? MyComponent : ""
//] // remove comment for var1
}
}
var MyComponent = {
controller: function() {
return {
onunload: function() {
console.log("unloaded!")
}
}
},
view: function() {
return m("h1", "My component")
}
}
var MainCompCtrl = function() {
var ctrl = this
ctrl.name = "test";
}
var MainCompView = function(ctrl, args) {
var partComp = m.component(MyApp);
var part_myComp = m(".row", [ m(".col-md-2", [partComp] ) ]);
var part5 = m("[id='2']", {class : 'commandContainer'}, "2", [part_myComp]);
return part5;
};
// var1 working
//m.mount(document.body, MyApp)
// var2 not working
m.mount(document.body, m.component(
{controller : MainCompCtrl, view : MainCompView}));
Here is a fiddle with the not working variant var2:
http://jsfiddle.net/1f7uauav/
The error message is:
TypeError: data is undefined
if (data.subtree === "retain") return cached;
To see the working var1 please remove comment as indicated in the fiddle (line 6, 9, 42) and comment lines 45 and 46. Now you can see the desired result, but this way I can't use MyApp inside other components.
So, what's wrong with this code in var2?
Thanks,
Stefan
Problem solved, in JavaScript never let a return be followed by a line break like this:
return //[ // remove comment for var1
m("button[type=button]", {onclick: function() {ctrl.loaded = false}})
, ctrl.loaded ? MyComponent : ""
//] // remove comment for var1
Sorry for this, Stefan