zipObject in lodash v.4.x.x - node.js

According to the documentation of lodash v3.10.1, it is possible to use _.zipObject such like this:
_.zipObject([['fred', 30], ['barney', 40]]);
// => { 'fred': 30, 'barney': 40 }
but in lodash v.4.15.0 I,m gettin this:
_.zipObject([['fred', 30], ['barney', 40]]);
{ 'fred,30': undefined, 'barney,40': undefined }

I've found a function I need in lodash v4.15.0. This function is fromPairs

Related

Using 'moment-weekday-calc' in node.js Typescript

Unable to use the Javascript plugin 'moment-weekday-calc' in a Node.Js Typescript project.
moment-weekday-calc does not have a typed version.
My code as written in Javascript:
const moment = require('moment');
require('moment-weekday-calc');
const result = moment().dateRangeToDates({
rangeStart,
rangeEnd,
exclusions,
weekdays: [1, 2, 3, 4, 5]
});
Potential Typescript code:
import * as moment from 'moment';
import 'moment-weekday-calc';
const result = moment().dateRangeToDates({
rangeStart,
rangeEnd,
exclusions,
weekdays: [1, 2, 3, 4, 5],
})
Error: Property 'dateRangeToDates' does not exist on type 'Moment'.ts(2339)
I've tried something like declare module 'moment-weekday-calc' but still no luck and I think moment-weekday-calc is unable to add the new modules to moment.
Thanking you in anticipation.
To just make it works, you can extend moment to include 'moment-weekday-calc' functions using TypeScript's declaration merging. But you have to define each functions yourself. And then just use require('moment-weekday-calc') in where you want to use those functions.
To use isoWeekdayCalc/weekdayCalc from 'moment-weekday-calc':
import moment from 'moment';
declare module "moment" {
interface Moment {
isoWeekdayCalc(d1: Date | string, d2: Date | string, weekDays: number[], exclusions?: string[], inclusion?: string[]): number
weekdayCalc(d1: Date | string, d2: Date | string, weekDays: string[] | number[], exclusions?: string[], inclusion?: string[]): number
}
}
Another work around, just simply add //#ts-ignore before your call the functions
//#ts-ignore
moment().weekdayCalc('1 Apr 2015','31 Mar 2016',[1,2,3,4,5],['6 Apr 2015','7 Apr 2015'],['10 Apr 2015']); //260

Best way to navigate throught a JSON in Node while validating the path

I'm trying to get some info out of a API call in Nodejs, structured something like a JSON:
{
"generated":"2019-11-04T09:34:11+00:00",
"event":{
"id":"19040956",
"start_":"2019-11-16T11:30:00+00:00",
"event_context":{
"sport":{
"id":"1",
"name":"Soccer"
}
}
}
}
I'm not sure about the presence of none of these fields(Json could be incomplete).
Is there a better way to get the value of "name" in JSON.event.event_context.sport.name without an ugly if to not get errors like "cannot get field 'sport' of undefined"?
Currently, I'm doing
if(json.event && json.event.event_context && json.event.event_context.sport) {
return json.event.event_context.sport.name;
}
Is there a better way?
Thank you!
what do you mean by saying "I'm not sure about the presence of none of these fields"?
i don't understand what your'e trying to achieve.
Looks like there is also an interesting package that will allow more conditions on searching json :
https://www.npmjs.com/package/jspath
let getNested = (path, obj) => {
return path.split(".").reduce( getPath, obj);
}
let getPath = (path, key) => {
return (path && path[key]) ? path[key] : null
}
let test = {
"foo": "bar",
"baz": { "one": 1, "two": ["to", "too", "two"] },
"event": { "event_context": { "sport": { "name": "soccer" } } }
}
console.log(getNested("none", test))
console.log(getNested("baz.one", test))
console.log(getNested("baz.two", test))
console.log(getNested("event.event_context.sport.name", test))
You can use lodash get to get a potentially deeply-nested value, and also specify a default in case it doesnt exist.
Example
const _ = require('lodash');
const my_object = {
"generated":"2019-11-04T09:34:11+00:00",
"event":{
"id":"19040956",
"start_":"2019-11-16T11:30:00+00:00",
"event_context":{
"sport":{
"id":"1",
"name":"Soccer"
}
}
};
_.get(my_object, 'event.event_context.sport.name'); // "Soccer"
_.get(my_object, 'event.event_context.sport.nonExistentField', 'default val'); // "default val"
Article: https://medium.com/#appi2393/lodash-get-or-result-f409e73e018b
You can check by using a function to check object keys like :
function checkProperty(checkObject, checkstring){
if(!checkstring)
return false;
var propertiesKeys = checkstring.split('.');
propertiesKeys.forEach(element => {
if(!checkObject|| !checkObject.hasOwnProperty(element)){
return false;
} else {
checkObject= checkObject[element];
}
})
return true;
};
var objectToCheck = {
"generated":"2019-11-04T09:34:11+00:00",
"event":{
"id":"19040956",
"start_":"2019-11-16T11:30:00+00:00",
"event_context":{
"sport":{
"id":"1",
"name":"Soccer"
}
}
}
}
if (checkProperty(objectToCheck ,'event.event_context.sport.name'))
console.log('object to find is : ', objectToCheck .event.event_context.sport.name;)
Yeah there are better ways!
For example, you could use lodash's get() method to reach a nested value.
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// => 3
But there is also a native solution.
Currently (11.2019) only Babel can handle this.
I am speaking of Optional chaining. It's new in the Ecmascript world.
Why I like it? Look here!
// Still checks for errors and is much more readable.
const nameLength = db?.user?.name?.length;
What happens when db, user, or name is undefined or null? With the optional chaining operator, JavaScript initializes nameLength to undefined instead of throwing an error.
If you are using Babel as a compiler then you could use it now.
Related link: https://v8.dev/features/optional-chaining

How to include nodejs package into the script

I have faced a very simple problem. I want to use a pakcage named Rbush in my javascript script in nodejs.
I have installed it using npm install rbush command and when I try to use it It raises this error
ReferenceError: RBush is not defined
here is my code
const t=require('rbush');
const tree = new RBush();
const item = {
minX: 20,
minY: 40,
maxX: 30,
maxY: 50,
foo: 'bar'
};
tree.insert(item);
I know that I have to include it into my script and I have done that using require function but it seems that it does not add the library there.I also tried the following method but it still does not work.
const tree=require('rbush');
const item = {
minX: 20,
minY: 40,
maxX: 30,
maxY: 50,
foo: 'bar'
};
tree.insert(item);
Node modules export different types, so it's important to check the docs and see what you 'get' when you require the module. The usage docs for rbush are not great in this respect, but it exports a class, so your first example is almost correct.
The variable you assign the module to is how you need to reference it in your code. So instead of assigning require('rbush') to t, you probably want to assign it to RBush. (You can name it whatever you want, but if you're going to call new RBush(), then you need to use that name when you require it, const RBush = require('rbush');
const RBush = require('rbush');
const tree = new RBush();
const item = {
minX: 20,
minY: 40,
maxX: 30,
maxY: 50,
foo: 'bar'
};
tree.insert(item);

forEach on an Array

I'm a little baffled. For some reason this won't work:
[1, 2, 3].forEach(function(num) {
console.log(num)
})
I get this error:
TypeError: Cannot call method 'forEach' of undefined
However, this will:
var nums = [1, 2, 3]
nums.forEach(function(num) {
console.log(num)
})
Anyone have any idea what's going on here?
So, it turns out it was because I'm not using semicolons, and the preceding code conflicted.
var foo = 'bar'
[1, 2, 3].forEach(function(num) {
console.log(num)
})
This is valid in both this jsbin: http://jsbin.com/kawatevovabu/1/edit
and in version v0.10.26 of node.js. Perhaps this is a platform issue?

forEach using generators in Node.js

I'm using Koa.js framework and Mongoose.js module.
Normally to get a result from MongoDB I code like this:
var res = yield db.collection.findOne({id: 'my-id-here'}).exec();
But I need to execute this line for every element of an array named 'items'.
items.forEach(function(item) {
var res = yield db.collection.findOne({id: item.id}).exec();
console.log(res) // undefined
});
But this code doesn't run as yield is in the function. If I write this:
items.forEach(function *(item) {
var res = yield db.collection.findOne({id: item.id}).exec();
console.log(res) // undefined
});
I'm not getting the result in res variable either. I tried to use 'generator-foreach' module but that didn't worked like this.
I know that this is my lack of knowledge about the language literacy of Node.js. But can you guys help me finding a way how to do this?
You can yield arrays, so just map your async promises in another map
var fetchedItems = yield items.map((item) => {
return db.collection.findOne({id: item.id});
});
The accepted answer is wrong, there is no need to use a library, an array is already an iterable.
This is an old question, but since it has no correct answer yet and it appears on the first page on google search for the key terms "iterators and forEach" I will respond the question:
There is no need to iterate over an array, since an array already conforms to the iterable API.
inside your generator just use "yield* array" (note the * )
yield* expression is used to delegate to another generator or iterable object
Example:
let arr = [2, 3, 4];
function* g2() {
yield 1;
yield* arr;
yield 5;
}
var iterator = g2();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
For examples and in depth information visit:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*
Thanks guys, I've done this using the 'CO' module. Thanks.
var co = require('co');
items.forEach(co(function* (item) {
var img = yield db.collection.findOne({id: item.id}).exec();
}));
EDIT: With the latest version of CO, you need co.wrap() for this to work.

Resources