I have a Angular service I want to test, one get function returns transformed data:
getSomeThings(pageSize) {
return this.http
.get(`../assets/things.json`)
.map((response) => response.json())
.toPromise()
.then(response => {
return response.map((thing) => {
return new Thing(thing);
});
}).then(response => {
response.slice(0, pageSize)
});
}
}
I'm testing this as below:
describe('ThingsService', () => {
let service: ThingsService;
let mockHttp;
const things = [{ id: 1, title: 'hello' }, { id: 2, title: 'hello' }, { id: 3, title: 'hello' }, { id: 4, title: 'hello' },
{ id: 5, title: 'hello' }, { id: 6, title: 'hello' }, { id: 7, title: 'hello' }, { id: 8, title: 'hello' }, { id: 9, title: 'hello' },
{ id: 10, title: 'hello' }, { id: 11, title: 'hello' }, { id: 12, title: 'hello' }];
beforeEach(() => {
mockHttp = new Http(undefined, undefined)
service = new ThingsService(mockHttp);
spyOn(mockHttp, 'get').and.returnValue(Observable.of(things)).and.callThrough();
});
it('should have a length of 10', async(() => {
mockHttp.get.and.returnValue(Observable.of(things));
return service.getThings(10)
.then((returnedThings: any[]) => {
expect(returnedThings.length).toBe(10)
});
}));
});
This returns an error:
response.json is not a function
things[] has a length of 12, but there's a slice in the final then() which should only return 10.
I'm quite new to Jasmine so could've easily missed some fundamentals here. Any help appreciated
const things = {
json:function(){
return [{ id: 1, title: 'hello' }, { id: 2, title: 'hello' }, { id: 3, title: 'hello' }, { id: 4, title: 'hello' },
{ id: 5, title: 'hello' }, { id: 6, title: 'hello' }, { id: 7, title: 'hello' }, { id: 8, title: 'hello' }, { id: 9, title: 'hello' },
{ id: 10, title: 'hello' }, { id: 11, title: 'hello' }, { id: 12, title: 'hello' }];
}
}
Related
This question already has answers here:
How can I group an array of objects by key?
(32 answers)
Closed 17 days ago.
I have the following data structure in its simplest form:
items: [
{ id: 1, account: 'acct_101' },
{ id: 2, account: 'acct_52' },
{ id: 3, account: 'acct_33' },
{ id: 4, account: 'acct_101' },
{ id: 5, account: 'acct_101' },
]
I would like to separate the items into groups based on their account data. The data is dynamic; I don't know in advance what the account numbers may be.
I can loop through the data:
items.map((item) => (
console.log("item account: ", item.account)
))
Yet unsure how to match if an item.account already exists and if so add to an existing data object, if not create a new object group.
The desired output could like like this:
item_groups: [
{
acct_101: [
{ id: 1, account: 'acct_101' },
{ id: 4, account: 'acct_101' },
{ id: 5, account: 'acct_101' },
],
acct_52: [
{ id: 2, account: 'acct_52' },
],
acct_33: [
{ id: 2, account: 'acct_33' },
],
}
]
Try like below:
const items = [
{ id: 1, account: 'acct_101' },
{ id: 2, account: 'acct_52' },
{ id: 3, account: 'acct_33' },
{ id: 4, account: 'acct_101' },
{ id: 5, account: 'acct_101' },
]
const output = items.reduce((prev, curr) => {
if(prev[curr.account]) {
prev[curr.account].push(curr)
} else {
prev[curr.account] = [curr]
}
return prev
}, {})
console.log([output])
More shorter form:
const items = [
{ id: 1, account: 'acct_101' },
{ id: 2, account: 'acct_52' },
{ id: 3, account: 'acct_33' },
{ id: 4, account: 'acct_101' },
{ id: 5, account: 'acct_101' },
]
const output = items.reduce((prev, curr) => {
prev[curr.account] = (prev[curr.account] ?? []).concat(curr)
return prev
}, {})
console.log([output])
Using Array.prototype.reduce()
For your desired output I think you need to use reduce higher order function.
So your code will be :
const itemGroups = items.reduce((acc, item) => {
const account = item.account;
if (acc[account]) {
acc[account].push(item);
} else {
acc[account] = [item];
}
return acc;
}, {});
console.log(itemGroups);
Output :
{
acct_101: [
{ id: 1, account: 'acct_101' },
{ id: 4, account: 'acct_101' },
{ id: 5, account: 'acct_101' }
],
acct_52: [ { id: 2, account: 'acct_52' } ],
acct_33: [ { id: 3, account: 'acct_33' } ]
}
const arr = [{
id: 1,
account: 'acct_101'
},
{
id: 2,
account: 'acct_52'
},
{
id: 3,
account: 'acct_33'
},
{
id: 4,
account: 'acct_101'
},
{
id: 5,
account: 'acct_101'
},
];
const retObj = {};
for (let i = 0; i < arr.length; i++) {
retObj[arr[i]["account"]] = arr.filter(item => item.account == arr[i]["account"]);
}
console.log(retObj)
can someone help me with this?
I need a function that given a fieldID, searchs within objects and returns the objectID that fieldID is in.
const objects = [
{
objectID: 11,
fields: [
{ id: 12, name: 'Source ID' },
{ id: 12, name: 'Source ID' },
],
},
{objectID: 14,
fields: [
{ id: 15, name: 'Creator' },
],},
{objectID: 16,
fields: [
{ id: 17, name: 'Type' },
{ id: 18, name: 'Name' },
{ id: 19, name: 'Description' },
],},
];
SOLVED:
Got it working like this:
const getObjectID = fieldId => {
for (const object of objects) {
if (object.fields.find(field => field.id === fieldId)) {
return object.objectID;
}
}
};
This will work:
const getObjectId = (fieldID) => {
const object = objects.find(object => object.fields.find(field => field.id === fieldID )!== undefined)
if(object) return object.objectID;
return null
}
Using the find array method:
const objects = [
{ objectId: 1, fields: ["aaa"] },
{ objectId: 2, fields: ["bbb"] },
{ objectId: 3, fields: ["ccc"] },
];
const getObjectId = (id) => objects.find(object.objectId === id);
console.log(getObjectId(2));
// { objectId: 2, fields: ["bbb"] }
Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
I have an array form lke this
const options = [
{
id: 1,
content: 'Hello'
},
{
id: 2,
content: 'Hi'
}
]
const answers = [
{
id: 400,
content: 'World',
optionKey: 1
},
{
id: 500,
content: 'There',
optionKey: 2
}
]
expected output
const expecetedOutput = [
{
option: {
id: 1,
content: 'Hello'
},
answer: {
id: 400,
content: 'World'
}
},
{
option: {
id: 2,
content: 'Hi'
},
answer: {
id: 500,
content: 'There'
}
}
];
What i have tried
i have tried using map and find but the result still not as expected
const optionWithAnswer = answers.map((answer) => {
return {
option: options.find((option) => option.id === answer.optionKey),
answer: answers.find((answer) => answer.optionKey === options.find((option) => option.id === answer.optionKey).id)
}
})
result i got. the answer will always found the first index of answer array
[
{
option: { id: 1, content: 'Hello' },
answer: { id: 400, content: 'World', optionKey: 1 }
},
{
option: { id: 2, content: 'Hi' },
answer: { id: 400, content: 'World', optionKey: 1 }
}
]
what i'm supposed to do. is this something that should accomplish using reduce ?
options.map(opt => ({
option: opt,
answer: answers.find(i => i.optionKey === opt.id)
}));
I'm trying to make two objects join in the following way.
I have these arrays.
Sets:
const sets = [
{
set_id: 1,
title: 'Mugs'
},
{
set_id: 2,
title: 'Phone Cases'
},
{
set_id: 3,
title: 'Pillows'
}
];
and products:
const products = [
{
product_id: 101,
title: 'Funny Pillow',
set: 3
},
{
product_id: 102,
title: 'Motivational Mug',
set: 1
},
{
product_id: 103,
title: 'Cool Phone Case',
set: 2
}
];
My goal here is to join a product to its matching set using code.
So a set would look something like this.
{
set_id: 1,
title: 'Mugs',
products: [
{ product_id: 102,
title: 'Motivational Mug',
set: 1
}
]
}
I've been trying this for hours, thanks in advance!
You just have to do map on sets and filter on products by set_id
const sets = [
{
set_id: 1,
title: "Mugs",
},
{
set_id: 2,
title: "Phone Cases",
},
{
set_id: 3,
title: "Pillows",
},
];
const products = [
{
product_id: 101,
title: "Funny Pillow",
set: 3,
},
{
product_id: 102,
title: "Motivational Mug",
set: 1,
},
{
product_id: 103,
title: "Cool Phone Case",
set: 2,
},
];
const res = sets.map((set) => ({
...set,
products: products.filter((product) => product.set === set.set_id),
}));
console.log(res);
.as-console-wrapper { max-height: 100% !important; }
Can't get the Array item by using method() while passing index as argument
it shows as undefined
export class DataService {
public list = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
]
getList() {
return this.list;
}
update(num, updated) {
let list = this.getList()
console.log(typeof (num))
console.log(this.list[num])
}
Your array contains objects, but you want to search by id which is a property of those objects. You have to use filter:
console.log(this.list.find(el => el.id === id))