Testing a mocked Observable converted to a promise in Angular - javascript

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

Loop through map and push to a new object group if items have matching values [duplicate]

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)

Search for value contained in array of objects in property of object contained in array

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

Array javascript to match answer and questions by id

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)
}));

Make objects with a matching property join in an array

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; }

Cant retrieve the data from the Array by using method(passing) index as argument

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))

Categories

Resources