Lodash - Retrieve an array of values for all object properties - lodash

I have something like
const payload = [{'name':'john doe', 'company': 'abc', 'age': 35},
{'name':'jane doe', 'company': 'def', 'age': 36}]
_.map(users, "name") => ['john doe', 'jane doe']
_.map(users, "company") => ['abc', 'def']
I want to have one call to retrieve the name, company and age from the payload. I don't want to make 3 calls with the map function. How can I do this? Because my payload is huge with a lot of properties.
Thanks!

Using lodash, you can map the objects to their values, and unzip the result:
const payload = [{'name':'john doe', 'company': 'abc', 'age': 35}, {'name':'jane doe', 'company': 'def', 'age': 36}];
const result = _(payload)
.map(_.values) // map to value arrays
.unzip() // unzip the arrays
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
The same idea works without lodash by mapping the objects into value arrays, and then transposing the values using reduce:
const payload = [{'name':'john doe', 'company': 'abc', 'age': 35}, {'name':'jane doe', 'company': 'def', 'age': 36}];
const result = payload
.map(Object.values) // map to value arrays
.reduce((t, arr) => { // transpose the arrays
arr.forEach((v, i) => (t[i] || (t[i] = [])).push(v));
return t;
}, []);
console.log(result);

You can use lodash#pick wrapped inside a lodash#partial as the iteratee for lodash#map.
const result = _.map(payload, _.partial(_.pick, _, ['name', 'company']));
const payload = [{
'name': 'john doe',
'company': 'abc',
'age': 35
},
{
'name': 'jane doe',
'company': 'def',
'age': 36
}
];
const result = _.map(payload, _.partial(_.pick, _, ['name', 'company']));
console.log(result);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Related

Nest js: How to received a dto field with array of predefined strings

I have a dto which is called product and it has a field called units....which received array of strings and this strings are predefined.....
my valid strings are predefined in a array ...
let validItems = ['a', 'b', 'c', 'd', 'e']
the data I want to be accepted by my dto is ...
{
product_id: 1,
units: ['a', 'b', 'c']
}
{
product_id: 2,
units: ['c', 'e', 'd']
}
{
product_id: 3,
units: ['e', 'b', 'a']
}
my current dto(not requirement satisfied) is =>
export class Product {
#IsString({ message: 'Product id must be a string' })
product_id: string;
#IsArray({ message: 'unit must be array' })
#IsString({ each: true, message: 'must be a string' })
units: string[];
}
what will be my DTO in nest.js. As I am new to nest.js so kindly provide me some good docs for this decorators
😛 I tried a lot and found a way to solve this problem.
I spent quite some time on the swagger docs for an array of strings.
import { ApiProperty } from "#nestjs/swagger";
import { IsArray, IsString } from "class-validator";
export class MenuOptionsByNames {
#ApiProperty({ isArray: true, example: ["size_external_party"] })
#IsArray()
#IsString({ each: true, message: "Each item should be string" })
menu_names: Array<string>;
}

Ramda reduce from array to object?

How can I switch from array to object data type in pipeline using ramda's reduce in point-free style?
I would like to achieve this:
(nodes) => nodes.reduce((acc, node: any) => {
acc[node.id] = {
out: node.outgoing_explicit,
in: node.incoming_explicit
};
return acc;
}, {})
Index the nodes by id, and the map them and use R.applySpec to change to the in/out format:
const { pipe, indexBy, map, applySpec, prop } = R
const fn = pipe(
indexBy(prop('id')),
map(applySpec({
out: prop('outgoing_explicit'),
in: prop('incoming_explicit'),
}))
)
const nodes = [{ id: 1, outgoing_explicit: 'abc1', incoming_explicit: 'xyz1' }, { id: 2, outgoing_explicit: 'abc2', incoming_explicit: 'xyz2' }, { id: 3, outgoing_explicit: 'abc3', incoming_explicit: 'xyz3' }]
const result = fn(nodes)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
this could also be a solution:
const spec = {
in: R.prop('incoming_explicit'),
out: R.prop('outgoing_explicit'),
}
const fn = R.reduceBy(
R.flip(R.applySpec(spec)),
null,
R.prop('id'),
);
const data = [
{ id: 'a', incoming_explicit: 'Hello', outgoing_explicit: 'World' },
{ id: 'b', incoming_explicit: 'Hello', outgoing_explicit: 'Galaxy' },
{ id: 'c', incoming_explicit: 'Hello', outgoing_explicit: 'Universe' },
{ id: 'd', incoming_explicit: 'Hello', outgoing_explicit: 'Dimension' },
];
console.log(
fn(data),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
The solutions involving applySpec are probably best, but just for variety, here's an alternative:
const convert = pipe (
map (juxt ([prop('id'), props(['incoming_explicit', 'outgoing_explicit'])])),
fromPairs,
map (zipObj (['in', 'out']))
)
const nodes = [{id: 'foo', outgoing_explicit: 43, incoming_explicit: 42}, {id: 'bar', outgoing_explicit: 20, incoming_explicit: 10}, {id: 'baz', outgoing_explicit: 309, incoming_explicit: 8675}]
console .log (convert (nodes))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script>const {pipe, map, juxt, prop, props, fromPairs, zipObj} = R </script>
`juxt' is a bit of an oddball function. It works like this:
juxt([f, g, h, ...]) //=> (a, b, ...) -> [f(a, b, ...), g(a, b, ...), h(a, b, ...), ...]

Joi validate array of objects with when condition

First of all, sorry for bad English.
I can't find any docs about this.
WHAT I WANT TO DO
const docs = {
type: 'a', // ['a',' 'b', 'c'] is available.
items: [
{
a: 123,
b: 100 // => This value only available when type is 'a' or 'b'. otherwise, forbidden.
}
]
};
MY JOI SCHEMA(NOT WORKED)
Joi.object({
type: Joi.string().valid('a', 'b', 'c').required(),
items: Joi.array()
.items(
Joi.object({
a: Joi.number().required()
b: Joi.number()
})
)
.when('type', {
is: Joi.string().valid('a', 'b'),
then: Joi.array().items(Joi.object({ b: Joi.number().required() })),
otherwise: Joi.array().items(Joi.object({ b: Joi.number().forbidden() }))
})
})
This code is not working correctly.
When type is 'c', it validate passed.
How can I fix this?
You have added .items() to items: Joi.array() which overrides the .when() condition, try using
Joi.object({
type: Joi.string().valid('a', 'b', 'c').required(),
items: Joi.array()
.when('type', {
is: Joi.string().valid('a', 'b'),
then: Joi.array().items(Joi.object({
a: Joi.number().required(),
b: Joi.number().required()
})),
otherwise: Joi.array().items(Joi.object({
a: Joi.number().required()
}))
})
})
example

Ramda: Is there a way to find particular key value is nested object?

I want to find particular key value is nested object or not.
{
'a': {
'area': 'abc'
},
'b': {
'area': {
'city': 'aaaa',
'state': 'ggggg'
}
}
}
In above example, I want to find 'a' and 'b' is object or nested object?
If you want to know whether all keys in the object contain nested objects then one possible solution is to convert all of the values of the object to boolean values using R.map and R.propSatisfies, representing whether the nested property was an object or not.
const fn = R.map(R.propSatisfies(R.is(Object), 'area'))
const example = {
'a': {
'area': 'abc'
},
'b': {
'area': {
'city': 'aaaa',
'state': 'ggggg'
}
}
}
console.log(fn(example))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
If you just want to know whether a specific key of an object contains a nested object, then you can do so with a composition of R.prop and R.propSatisfies.
const fn = R.pipe(R.prop, R.propSatisfies(R.is(Object), 'area'))
const example = {
'a': {
'area': 'abc'
},
'b': {
'area': {
'city': 'aaaa',
'state': 'ggggg'
}
}
}
console.log('a:', fn('a', example))
console.log('b:', fn('b', example))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

How to "Actually" Test an Angular 2 Service

I am new to testing calls to an API. I have this unit test code in Angular 2:
beforeEach(inject([JobListService, MockBackend],
(testedService: JobListService, mockBackend: MockBackend) => {
service = testedService;
backend = mockBackend;
backend.connections.subscribe((c) => {
c.mockRespond(new Response(
new ResponseOptions({body: JSON.stringify(JOBLISTMOCK)})
));
});
}));
describe('getAll', () => {
it('should return jobs', () => {
service.getAll(1, 10, '0').subscribe(response => {
console.log(response.data.length);
expect(response.data.data.length).toBeGreaterThan(0);
});
});
it('should return jobs based on company ID', () => {
service.getAll(1, 10, '26').subscribe(response => {
console.log(response.data.data.length);
expect(response.data.data.length).toEqual(1);
});
});
});
it has the url structure:
http://example.com/api/jobs/1/10/26
where first and second segment is pagination and the 3rd segment is a company ID.
I am testing this service function:
getAll(page: number, pageSize: number, company: string): Observable<any> {
if (company !== 'null') {
return this.http.get(`${this.conf.apiUrl}/jobs/companies/get/${page}/${pageSize}/${company}`)
.map((response: Response) => response.json());
} else {
return this.http.get(`${this.conf.apiUrl}/jobs/companies/get/${page}/${pageSize}/0`)
.map((response: Response) => response.json());
}
}
I have this mock response:
{
'id': 13,
'title': 'Sample Title',
'valid_from': '2016-01-01',
'valid_to': '2016-02-01',
'field_id': '1',
'image': '',
'description': null,
'user_id': 0,
'company_id': 26,
'created_at': '2017-01-23 14:37:01',
'updated_at': '2017-01-23 14:37:01',
'fields': {
'field_id': 1,
'name': 'Respiratory Therapy Technician'
}
},
{
'id': 15,
'title': 'Sample Title',
'valid_from': '2016-01-01',
'valid_to': '2016-02-01',
'field_id': '1',
'image': 'asd',
'description': 'This is my sample des',
'user_id': 0,
'company_id': 0,
'created_at': '2017-01-23 14:37:27',
'updated_at': '2017-01-23 14:37:27',
'fields': {
'field_id': 1,
'name': 'Respiratory Therapy Technician'
}
}
}
the 2nd one fails, obviously, because my mock response is set to companies that have 0 and 26 as IDs.
I get that I am mocking a response via a mockbackend but what I want is to test the function such that getAll() returns only the jobs with company_id 26. But my mock response is static. Is there anyway that I can make a "dynamic mock backend" that will work with what I want to test?