Ramda: Translate for-in loop to declarative method - ramda.js

I'm new on Ramda. May I know how to translate the code below using Ramda
I found some functions like keys, keysIn, but i have no idea how to apply them.
Thanks.
const params = {
data: {
a: 'aaa',
b: 'bbb',
c: 'ccc',
}
}
let formData = new FormData();
for (let key in params.data) {
formData.append(key, params.data.key);
}

To follow from what #scott said, you wouldn't really want to cause side effects from within ramda (especially from within a map fn), but if for some reason you need to you could do something like the following:
const params = {
data: {
a: 'aaa',
b: 'bbb',
c: 'ccc',
}
}
let formData = new FormData();
let appender = flip(invoker(2, 'append'))(R.__, R.__, formData)
mapObjIndexed(appender)(params.data)
formData.get('a') === 'aaa' // -> true
Using #scott's suggestion of invoker, we can build an appender function which takes a key and a value, and calls formData.append with those. To achieve point-free style it ends up quite messy though. It can be a bit more explicit like so:
let appender = form => (v, k) => form.append(k, v);
mapObjIndexed(appender(formData))(params.data)
This has the added benefit of allowing us to provide the formData later, so whilst appender is still impure, it's less coupled

Related

How can I use the same value as written in the Json during the same test execution in the testcafe

I have been trying to use the value from the JSON that I have got added successfully using fs.write() function,
There are two test cases in the same fixture, one to create an ID and 2nd to use that id. I can wrote the id successfully in the json file using fs.write() function and trying to use that id using importing json file like var myid=require('../../resources/id.json')
The json file storing correct id of the current execution but I get the id of first test execution in 2nd execution.
For example, id:1234 is stored during first test execution and id:4567 is stored in 2nd test execution. During 2nd test execution I need the id:4567 but I get 1234 this is weird, isn't it?
I use it like
t.typeText(ele, myid.orid)
my json file contains only id like {"orid":"4567"}
I am new to Javascript and Testcafe any help would really be appreciated
Write File class
const fs = require('fs')
const baseClass =require('../component/base')
class WriteIntoFile{
constructor(orderID){
const OID = {
orderid: orderID
}
const jsonString = JSON.stringify(OID)
fs.writeFile(`resources\id.json`, jsonString, err => {
if (err) {
console.log('Error writing file', err)
} else {
console.log('Successfully wrote file')
}
})
}
}
export default WriteIntoFile
I created 2 different classes in order to separate create & update operations and call the functions of create & update order in single fixture in test file
Create Order class
class CreateOrder{
----
----
----
async createNewOrder(){
//get text of created ordder and saved order id in to the json file
-----
-----
-----
const orId= await baseclass.getOrderId();
new WriteIntoFile(orId)
console.log(orId)
-----
-----
-----
}
}export default CreateOrder
Update Order class
var id=require('../../resources/id.json')
class UpdateOrder{
async searchOrderToUpdate(){
await t
***//Here, I get old order id that was saved during previous execution***
.typeText(baseClass.searchBox, id.orderid)
.wait(2500)
.click(baseClass.searchIcon)
.doubleClick(baseClass.orderAGgrid)
console.log(id.ordderid)
----
----
async updateOrder(){
this.searchOrderToUpdate()
.typeText(baseClass.phNo, '1234567890')
.click(baseClass.saveBtn)
}
}export default UpdateOrder
Test file
const newOrder = new CreateOrder();
const update = new UpdateOrder();
const role = Role(`siteurl`, async t => {
await t
login('id')
await t
.wait(1500)
},{preserveUrl:true})
test('Should be able to create an Order', async t=>{
await newOrder.createNewOrder();
});
test('Should be able to update an order', async t=>{
await update.updateOrder();
});
I'll reply to this, but you probably won't be happy with my answer, because I wouldn't go down this same path as you proposed in your code.
I can see a couple of problems. Some of them might not be problems right now, but in a month, you could struggle with this.
1/ You are creating separate test cases that are dependent on each other.
This is a problem because of these reasons:
what if Should be able to create an Order doesn't run? or what if it fails? then Should be able to update an order fails as well, and this information is useless, because it wasn't the update operation that failed, but the fact that you didn't meet all preconditions for the test case
how do you make sure Should be able to create an Order always runs before hould be able to update an order? There's no way! You can do it like this when one comes before the other and I think it will work, but in some time you decide to move one test somewhere else and you are in trouble and you'll spend hours debugging it. You have prepared a trap for yourself. I wrote this answer on this very topic, you can read it.
you can't run the tests in parallel
when I read your test file, there's no visible hint that the tests are dependent on each other. Therefore as a stranger to your code, I could easily mess things up because I have no way of knowing about it without going deeper in the code. This is a big trap for anyone who might come to your code after you. Don't do this to your colleagues.
2/ Working with files when all you need to do is pass a value around is too cumbersome.
I really don't see a reason why you need to same the id into a file. A slightly better approach (still violating 1/) could be:
const newOrder = new CreateOrder();
const update = new UpdateOrder();
// use a variable to pass the orderId around
// it's also visible that the tests are dependent on each other
let orderId = undefined;
const role = Role(`siteurl`, async t => {
// some steps, I omit this for better readability
}, {preserveUrl: true})
test('Should be able to create an Order', async t=>{
orderId = await newOrder.createNewOrder();
});
test('Should be able to update an order', async t=>{
await update.updateOrder(orderId);
});
Doing it like this also slightly remedies what I wrote in 1/, that is that it's not visible at first sight that the tests are dependent on each other. Now, this is a bit improved.
Some other approaches how you can pass data around are mentioned here and here.
Perhaps even a better approach is to use t.fixtureCtx object:
const newOrder = new CreateOrder();
const update = new UpdateOrder();
const role = Role(`siteurl`, async t => {
// some steps, I omit this for better readability
}, {preserveUrl:true})
test('Should be able to create an Order', async t=>{
t.fixtureCtx.orderId = await newOrder.createNewOrder();
});
test('Should be able to update an order', async t=>{
await update.updateOrder(t.fixtureCtx.orderId);
});
Again, I can at least see the tests are dependent on each other. That's already a big victory.
Now back to your question:
During 2nd test execution I need the id:4567 but I get 1234 this is weird, isn't it?
No, it's not weird. You required the file:
var id = require('../../resources/id.json')
and so it's loaded once and if you write into the file later, you won't read the new content unless you read the file again. require() is a function in Node to load modules, and it makes sense to load them once.
This demonstrates the problem:
const idFile = require('./id.json');
const fs = require('fs');
console.log(idFile); // { id: 5 }
const newId = {
'id': 7
};
fs.writeFileSync('id.json', JSON.stringify(newId));
// it's been loaded once, you won't get any other value here
console.log(idFile); // { id: 5 }
What you can do to solve the problem?
You can use fs.readFileSync():
const idFile = require('./id.json');
const fs = require('fs');
console.log(idFile); // { id: 5 }
const newId = {
'id': 7
};
fs.writeFileSync('id.json', JSON.stringify(newId));
// you need to read the file again and parse its content
const newContent = JSON.parse(fs.readFileSync('id.json'));
console.log(newContent); // { id: 7 }
And this is what I warned you against in the comment section. That this is too cumbersome, inefficient, because you write to a file and then read from the file just to get one value.
What you created is not very readable either:
const fs = require('fs')
const baseClass =require('../component/base')
class WriteIntoFile{
constructor(orderID){
const OID = {
orderid: orderID
}
const jsonString = JSON.stringify(OID)
fs.writeFile(`resources\id.json`, jsonString, err => {
if (err) {
console.log('Error writing file', err)
} else {
console.log('Successfully wrote file')
}
})
}
}
export default WriteIntoFile
All these operations for writing into a file are in a constructor, but a constructor is not the best place for all this. Ideally you have only variable assignments in it. I also don't see much reason for why you need to create a new class when you are doing only two operations that can easily fit on one line of code:
fs.writeFileSync('orderId.json', JSON.stringify({ orderid: orderId }));
Keep it as simple as possible. it's more readable like so than having to go to a separate file with the class and decypher what it does there.

How do I stub the monitor while testing react-dnd?

I'm trying to test my implementation of react-dnd, and in one of my drop functions I'm using the monitor.getInitialClientOffset() function to get an offset, and I'd like to stub this method to return a particular offset that I can then assert on, but I cannot figure this out. In my test I'm using
const WrappedContext = wrapInTestContext(ContextArea);
const page = mount(<WrappedContext />);
const manager = page.get(0).getManager();
const backend = manager.getBackend();
// Couple finds to get the right source and target ids
backend.simulateBeginDrag([sourceId])
backend.simulateHover([targetId])
backend.simulateDrop();
backend.simulateEndDrag();
(This is using the standard wrapInTestContext from https://gaearon.github.io/react-dnd/docs-testing.html)
The drop function is passed a monitor from the test backend and I don't see a way in the documentation to pass a stubbed version of it to any of the simulation methods.
So it turns out that you can access the monitor that the test backend is using and then stub out methods on it like this:
const manager = page.get(0).getManager();
const backend = manager.getBackend();
const monitor = manager.getMonitor();
sinon.stub(monitor, 'getInitialClientOffset', () => {
return {
x: 10,
y: 20,
};
});
sinon.stub(monitor, 'getDifferenceFromInitialOffset', () => {
return {
x: 2,
y: 4,
};
});
And then in the drop function those are the values that will be used in any sort of math you're using.

pass options to mongoose schema toJSON transform inline (in expressjs)?

I have a mongoose (3.1) 'Thing' schema whose toJSON I can customize in the following manner...
Thing.options.toJSON = {};
Thing.options.toJSON.transform = function (doc, ret, options){
// do something to ret, depending on options
}
As noted in the code comment, I would like to change the JSON representation given the value of options. I would like to pass these options in an expressjs action, maybe...
app.get(..., function (req ,res){
Thing.find({}, function(err, things){
var myOptions = {...} // something application stateful
return response.send(things) // MAYBE ADD OPTIONS HERE?
});
});
How do I modify expressjs to allow me to supply options?
Thanks,
G
IMHO, the accepted answer (#VladStirbu's) is wrong because the options are being set at the schema level. It's changing the schema, so those options will be available in subsequent calls, even if you don't request so explicitly.
The options should be set inline, individually for that call:
Regular call using express:
app.get(..., function (req ,res){
Thing.find({}, function(err, things){
return response.send(things);
});
});
Call using express, but passing inline options to toJSON():
app.get(..., function (req ,res){
Thing.find({}, function(err, things){
let toJSONOptions; // may be undefined, it's fine
if ( /* whatever condition you decide */ ) {
// this keeps the schema's original options:
toJSONOptions = Object.assign({ }, Thing.schema.options.toJSON);
// request to use original transform function, if any:
toJSONOptions.transform = true;
// set your own options to be passed to toJSON():
toJSONOptions._options = {...}; // whatever you need here
}
return response.send( things.map(e => e.toJSON(toJSONOptions)) );
});
});
No problem if toJSONOptions = undefined, it would be like a regular call to toJSON(), which is what express does when stringifying.
If you're using findOne() or findById(), then just return:
return response.send( thing.toJSON(toJSONOptions) );
This is the Mongoose commit that made me think of this:
https://github.com/Automattic/mongoose/commit/1161f79effc074944693b1799b87bb0223103220
You could pass options in the route handler by passing them to the schema options:
app.get(..., function (req ,res){
Thing.find({}, function(err, things){
Thing.schema.options.toJSON.myOptions = {...} // something application stateful
return response.send(things) // MAYBE ADD OPTIONS HERE?
});
});
this way, the options will be available in the transform function as a property of the options object:
Thing.options.toJSON.transform = function (doc, ret, options){
console.log(options.myOptions); // prints the app specific data provided earlier
}

How to retrieve stores based on the store id

I am creating a Memory store as
var someData = [
{id:1, name:"One"},
{id:2, name:"Two"}
];
store = new Memory({
data: someData,
id:”userStore”
});
I was wondering if there is a way to query the Memory store to return the store instance by id. Like
var storePresent = Memory.getById(“userStore”)
something similar to
dijit.registry.byId();
that returns the instance of dijit specified by id
To my knowledge, there is not a store registry as you describe. You will need to code this yourself in your application's controller code.
A store is a simple Object.
You could:
Pass the store manually around your code.
Code a registry AMD module (caution, here be dragons).
The only exception to this rule is if you're already using dojox/app as your controller layer. That has some named store abilities. If not, I would not recommend refactoring to use it.
There's no build-in static repository of memory stores in module dojo/store/Memory. If you need something like that, the easiest way is to write custom factory of memory stores that will hold the static references to all stores that are created:
define(["dojo/store/Memory"], function(Memory){
var repository = {}
return {
getStore: function(id) {
return repository[id]
},
createStore: function(id, params) {
var memory = new Memory(params)
repository[id] = memory
return memory
}
}
});
The usage:
require(["modules/MemoryRepository"], function(MemoryRepository) {
MemoryRepository.createStore("userStore", {data: someData})
...
var userStore = MemoryRepository.getStore("userStore")
})
If you are to create a lot of stores on demand, you should think of deregistering them (removing the references from the factory) as well. Memory issues are probably the reason something like that is not provided out-of-the-box.
Like the other answerers already said, there's no specific repository or registry for stores. However, the dijit/registry can be used to store the reference as well by using the dijit/registry::add() function, for example:
// Add to registry
registry.add(new Memory({
id: "userStore",
data: [{
name: "Smith",
firstname: "John"
}, {
name: "Doe",
firstname: "John"
}]
}));
Then you can retrieve it by using the dijit/registry::byId() function, for example:
// Query the store by using the registry
var person = registry.byId("userStore").query({
firstname: "John"
}).forEach(function(person) {
console.log(person.firstname + " " + person.name);
});
A full example can be found on JSFiddle: http://jsfiddle.net/mn94f/

WinJS Enumeration

How can I make an enumeration in WinJS?
I tried to make a class like this for example:
(function () {
"use strict";
var TaskEnum = WinJS.Class.define(
null,
{},
// The set of static members.
{
SUPERVISION: 1,
DIG: 2,
MAP: 3,
});
var Task = new TaskEnum();
WinJS.Namespace.define("ENUMS", {
TASK: {
get: function () {
return Task;
}
}
});
})();
But when I call ENUMS.TASK.DIG then DIG is undefined.
I even tried just this:
WinJS.Namespace.define("ENUMS", {
TASK: { SUPERVISION: 1, DIG: 2, MAP: 3, }
});
But when I call ENUMS.TASK.DIG then DIG is still undefined.
It seems like the Namespace.define does not work in that way?
Ohk, If i get you exact then , you want to define Enumeration in JavaScript?
right ?
For this case I don't think if it is done with WinJs or not on Windows Store App,
but I have two Suggestions as my answer :
1 ) Use C# as Runtime Component to perform This operations, by defining a function in c# and simply call it on your JavaScript.
See ,Creating a simple component in C#.
2 ) Enumerated types in JavaScript
Or See : WinJS.UI Namespace
http://207.46.99.208/pl-pl/library/windows/apps/br229782#enums_section
I might not understand what you're hoping to get out of the Namespace definition, but not just use core JavaScript?
window.ENUMS = {
TASK: {
SUPERVISION: 1,
DIG: 2,
MAP: 3
}
};
Then use it like you were trying to:
callSomeFunction(ENUMS.TASK.DIG);
Note that if you can restrict users to IE11 (not so difficult in Win8 apps) then you can make use of JavaScript constants through const as well.