I am learning DynamoDB and have difficulties understanding where to perform a reduction on data once a DynamoDB query has provided the results and where in the code it would go.
I would like to sum up the running_time_secs.
async function scanForResults () {
try {
var params = {
TableName: "Movies",
ProjectionExpression: "#yr, title, info.rating, info.running_time_secs, info.genres",
FilterExpression: "#yr between :start_yr and :end_yr",
ExpressionAttributeNames: {
"#yr": "year",
},
ExpressionAttributeValues: {
":start_yr": 1950,
":end_yr": 1985,
}
};
var result = await docClient.scan(params).promise()
console.log(JSON.stringify(result))
//const total = result.reduce((sum, result) => sum + result.info.running_time_secs, 0);
} catch (error) {
console.error(error);
}
}
scanForResults();
Thanks for any help.
EDITED
Maybe you can post the actual value of the result once you resolve it. It would be best to know the actual structure of the result value to better see how you should approach it. You can site the documentation for further reference. It is actually really helpful.
var result = [{
"title": "Piranha",
"year": 1978,
"info": {
"rating": 5.8,
"genres": ["Comedy", "Horror", "Sci-Fi"],
"running_time_secs": 5640
}
}]
var total = result.reduce((sum, result) => sum + result.info.running_time_secs, 0);
console.log(total);
var result2 = [{
"title": "Piranha",
"year": 1978,
"info": {
"rating": 5.8,
"genres": ["Comedy", "Horror", "Sci-Fi"],
"running_time_secs": 5640
}
},
{
"title": "Piranha2",
"year": 1980,
"info": {
"rating": 5.8,
"genres": ["Comedy", "Horror", "Sci-Fi"],
"running_time_secs": 5640
}
}
]
var total2 = result2.reduce((sum, result) => sum + result.info.running_time_secs, 0);
console.log(total2);
var resultObj = {
"title": "Piranha",
"year": 1978,
"info": {
"rating": 5.8,
"genres": ["Comedy", "Horror", "Sci-Fi"],
"running_time_secs": 5640
}
}
var totalObj = resultObj.reduce((sum, result) => sum + result.info.running_time_secs, 0);
console.log(totalObj);
I think base on the error you are receiving, result might not be an array. You can refer to the code snippet I posted. I used your code and just created the result array to mimic the result you get from the scan function. As you can see on the 3rd reduce function used on resultObj, I got the response error you got. reduce is an array method and using it to an object would result in such an error because object does not implement this method. Hence, I think that the result you are getting is not an array.
Related
Problem
I’m trying to return only the objects that don’t contain any of the names on the filteredEmployers list, against the employer attribute, from an API I'm retrieving the data from.
What I've tried
I have an alternative piece of code that seems to work fine when I don’t connect to the API (i.e. reading from hardcoded data), but when I connect to the API, even though I get the following response (when immediately logged after retrieval), the code then doesn’t execute…
{
"Pagination": {
"NumberOfPeople": 185,
"PageSize": 200,
"PageNumber": 1,
"NumberOfPages": 1
},
"People": [
{
"name": "TJ",
"job": "Software Engineer",
"organization": {
"company": {
"employer": "amazon",
"department": "IT"
}
},
"location": {
"city": "Boston",
"state": "Massachusetts"
}
},
{
"name": "Dominique",
"job": "CEO",
"organization": {
"company": {
"employer": "IBM",
"department": "IT"
}
},
"city": "Seattle",
"state": "Washington"
},
{
"name": "Enrique",
"job": "Engineer",
"organization": {
"company": {
"employer": "Bellkrieg Megasystems",
"department": "Construction"
}
},
"location": {
"address": {
"state": "New York",
"city": "New York City",
"zip": "11323"
}
}
},
{
"name": "Bob",
"job": "Project Manager",
"organization": {
"company": {
"employer": "Megasystems",
"department": "R&D"
}
},
"address": {
"location": {
"quadrant": {
"block": 1,
"state": "Texas",
"city": "Austin"
}
}
}
}
]
}
The code I’m trying to implement is here:
// constants and variables are defined here, including API credentials and the filteredEmployers array
//FYI const filteredEmployers = ['Megasystems', 'Bellkrieg'];
//the code then fetches the API data is here
.then((response) => {
return response.json();
})
.then((json) => {
//console.log(typeof json);
//console.log(json);
const people = Array.from(json).flatMap(o => o.People);
return people.filter(person => {
const employer = person?.organization?.company?.employer;
if (typeof employer !== 'string') return true;
const employerIsNotFiltered = filteredEmployers.every(
str => !employer.includes(str)
);
console.log("This is the outputted data: " + employerIsNotFiltered);
return employerIsNotFiltered;
});
})
The desired response is:
[
{
name: 'TJ',
job: 'Software Engineer',
organization: { company: [Object] },
location: { city: 'Boston', state: 'Massachusetts' }
},
{
name: 'Dominique',
job: 'CEO',
organization: { company: [Object] },
city: 'Seattle',
state: 'Washington'
}
]
Any recommendations on how to get this to execute, or alternatives to this method appreciated.
Thanks in advance
Reiterating my comment on your question: You just need to change the line
const people = Array.from(json).flatMap(o => o.People);
to
const people = json.People;
The JSON response that you included in the question is an object, and Response.json() returns a promise which resolves to an already parsed representation of the JSON text response, so in order to access the array at the People property, you only need json.People. Here is a runnable snippet based on the code and data that you showed:
// The JSON data, copied and pasted from the first code block of your question:
const json = `{"Pagination":{"NumberOfPeople":185,"PageSize":200,"PageNumber":1,"NumberOfPages":1},"People":[{"name":"TJ","job":"Software Engineer","organization":{"company":{"employer":"amazon","department":"IT"}},"location":{"city":"Boston","state":"Massachusetts"}},{"name":"Dominique","job":"CEO","organization":{"company":{"employer":"IBM","department":"IT"}},"city":"Seattle","state":"Washington"},{"name":"Enrique","job":"Engineer","organization":{"company":{"employer":"Bellkrieg Megasystems","department":"Construction"}},"location":{"address":{"state":"New York","city":"New York City","zip":"11323"}}},{"name":"Bob","job":"Project Manager","organization":{"company":{"employer":"Megasystems","department":"R&D"}},"address":{"location":{"quadrant":{"block":1,"state":"Texas","city":"Austin"}}}}]}`;
function mockFetch () {
return Promise.resolve({
json: () => Promise.resolve(JSON.parse(json)),
});
}
const filteredEmployers = ['Megasystems', 'Bellkrieg'];
mockFetch()
.then(response => response.json())
.then(json => {
// Change this line:
// const people = Array.from(json).flatMap(o => o.People);
// To:
const people = json.People;
return people.filter(person => {
const employer = person?.organization?.company?.employer;
if (typeof employer !== 'string') return true;
const employerIsNotFiltered = filteredEmployers.every(
str => !employer.includes(str)
);
return employerIsNotFiltered;
});
})
.then(console.log);
I have the following array
Array["MyArray",
{
"isLoaded":true,
"items":
[{
"id":"4",
"name":"ProductA",
"manufacturer":"BrandA",
"quantity":1,
"price":"25"
},{
"id":"1",
"name":"ProductB",
"manufacturer":"BrandB",
"quantity":5,
"price":"20"
}],
"coupons":null
}
]
I need to load product names and their quantity from the array.
const result = [key, value].map((item) => `${item.name} x ${item.quantity}`);
Here's one possible way to achieve the desired result:
const getProductsAndQuantity = ([k , v] = arr) => (
v.items.map(it => `${it.name} x ${it.quantity}`)
);
How to use it within the context of the question?
localforage.iterate(function(value, key, iterationNumber) {
console.log([key, value]);
const val2 = JSON.parse(value);
if (val2 && val2.items && val2.items.length > 0) {
console.log(val2.items.map(it => `${it.name} x ${it.quantity}`).join(', '))
};
});
How it works?
Among the parameters listed in the question ie, value, key, iterationNumber, only value is required.
The above method accepts the key-value pair as an array (of 2 elements) closely matching the console.log([key, value]); in the question
It uses only v (which is an object). On v, it accesses the prop named items and this items is an Array.
Next, .map is used to iterate through the Array and return each product's name and quantity in the desired/expected format.
Test it out on code-snippet:
const arr = [
"MyArray",
{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}
];
const getProductsAndQuantity = ([k, v] = arr) => (
v.items.map(
it => `${it.name} x ${it.quantity}`
)
);
console.log(getProductsAndQuantity());
I understood. You should learn about array methods such as map, filter, reduce. Here you go...
const items = [{
"id":"4",
"name":"ProductA",
"manufacturer":"BrandA",
"quantity":1,
"price":"25"
},{
"id":"1",
"name":"ProductB",
"manufacturer":"BrandB",
"quantity":5,
"price":"20"
}];
const result = items.map((item) => `${item.name} x ${item.quantity}`);
console.log(result);
I think I understand the question to say that the input is an array of objects, each containing an array of items. The key is that a nested array requires a nested loop. So, we iterate the objects and their internal items (see the lines commented //outer loop and // inner loop below)
Also, half-guessing from the context, it looks like the that the OP aims to assemble a sort of invoice for each object. First a demo of that, (and see below for the version simplified to exactly what the OP asks)...
const addInvoice = obj => {
let total = 0;
// inner loop
obj.invoice = obj.items.map(i => {
let subtotal = i.quantity * i.price;
total += subtotal
return `name: ${i.name}, qty: ${i.quantity}, unit price: ${i.price}, subtotal: ${subtotal}`
});
obj.invoice.push(`invoice total: ${total}`);
}
const objects = [{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}]
// outer loop
objects.forEach(addInvoice);
console.log(objects);
If my guess about the goal went to far, just remove the unit price, subtotal and total lines from the invoice function...
const objects = [{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}]
const summaryString = obj => {
return obj.items.map(i => `${i.name}, ${i.quantity}`);
}
const strings = objects.map(summaryString);
console.log(strings);
May I know if using reduce I can achieve the following where the properties of activatedItems and quarterItems are wrapped in one object i.e., modules.
{
"isExternalVisitor": false,
"modules": [
{
"moduleId": "e569da0e-44e6-4f75-96c4-bdd888678abd",
"code": "NEWQ2/SITENAME/2021-Q3-1",
"siteId": "10babdbe-5346-43e8-932a-4c7ae54dcb1b",
"activatedId": "2e03c658-3bbd-4332-bb1b-14fe56c7e753"
},
{
"moduleId": "588905b4-2c1d-49bf-a71f-84210405bc94",
"code": "NEWQ1/SITENAME/2021-Q1-2",
"siteId": "10babdbe-5346-43e8-932a-4c7ae54dcb1b",
"activatedId": "6c1691d2-7c37-4888-a446-9219fa9b9014"
}
],
"activatedItems": [
{
"activatedId": "2e03c658-3bbd-4332-bb1b-14fe56c7e753",
"stQuarterId": "b36d7e23-15e5-4f97-b52e-65757de4b264"
},
{
"activatedId": "6c1691d2-7c37-4888-a446-9219fa9b9014",
"stQuarterId": "01000f98-6470-440a-a833-95b199ab1f7a"
}
],
"quarterItems": [
{
"id": "b36d7e23-15e5-4f97-b52e-65757de4b264",
"checklistId": "8b479656-8cde-4bff-9c51-d5eca369bc76",
"fullName": "dsad",
"year": "2021-01-01T00:00:00",
"quarter": "2021-Q3",
"versions": 1
},
{
"id": "01000f98-6470-440a-a833-95b199ab1f7a",
"checklistId": "039f2584-1ca5-4ee3-b46f-cdf1887af7f6",
"fullName": "NEWQ1",
"year": "2021-01-01T00:00:00",
"quarter": "2021-Q1",
"versions": 2
}
]
}
This is the expected result where only one object has got all the data.
{
"isExternalVisitor": false,
"modules": [
{
"moduleId": "e569da0e-44e6-4f75-96c4-bdd888678abd",
"code": "NEWQ2/SITENAME/2021-Q3-1",
"siteId": "10babdbe-5346-43e8-932a-4c7ae54dcb1b",
"activatedId": "2e03c658-3bbd-4332-bb1b-14fe56c7e753",
"stQuarterId": "b36d7e23-15e5-4f97-b52e-65757de4b264",
"checklistId": "8b479656-8cde-4bff-9c51-d5eca369bc76",
"fullName": "dsad",
"year": "2021-01-01T00:00:00",
"quarter": "2021-Q3",
"versions": 1
},
{
"moduleId": "588905b4-2c1d-49bf-a71f-84210405bc94",
"code": "NEWQ1/SITENAME/2021-Q1-2",
"siteId": "10babdbe-5346-43e8-932a-4c7ae54dcb1b",
"activatedId": "6c1691d2-7c37-4888-a446-9219fa9b9014",
"stQuarterId": "01000f98-6470-440a-a833-95b199ab1f7a",
"checklistId": "039f2584-1ca5-4ee3-b46f-cdf1887af7f6",
"fullName": "NEWQ1",
"year": "2021-01-01T00:00:00",
"quarter": "2021-Q1",
"versions": 2
}
]
}
I tried the following and was able to merge them in one array, but however, the end result is not the same as above. Your kind help will be appreciated.
let modules = arr.modules;
let activatedItems = arr.activatedItems;
let quarterItems = arr.quarterItems;
let finalArr = [];
modules.forEach(module => {
activatedItems.forEach(item =>{
if(item.activatedId == module.activatedId)
{
quarterItems.forEach(quaItem => {
if(quaItem.id == item.stQuarterId){
finalArr.push(module);
finalArr.push(item);
finalArr.push(quaItem);
}
})
}
})
})
it seems you're just joining the arrays on index. If that's the case, a simple map will do! Just map over modules and use the index of the map callback function to grab the corresponding object from the other arrays.
const obj={isExternalVisitor:!1,modules:[{moduleId:"e569da0e-44e6-4f75-96c4-bdd888678abd",code:"NEWQ2/SITENAME/2021-Q3-1",siteId:"10babdbe-5346-43e8-932a-4c7ae54dcb1b",activatedId:"2e03c658-3bbd-4332-bb1b-14fe56c7e753"},{moduleId:"588905b4-2c1d-49bf-a71f-84210405bc94",code:"NEWQ1/SITENAME/2021-Q1-2",siteId:"10babdbe-5346-43e8-932a-4c7ae54dcb1b",activatedId:"6c1691d2-7c37-4888-a446-9219fa9b9014"}],activatedItems:[{activatedId:"2e03c658-3bbd-4332-bb1b-14fe56c7e753",stQuarterId:"b36d7e23-15e5-4f97-b52e-65757de4b264"},{activatedId:"6c1691d2-7c37-4888-a446-9219fa9b9014",stQuarterId:"01000f98-6470-440a-a833-95b199ab1f7a"}],quarterItems:[{id:"b36d7e23-15e5-4f97-b52e-65757de4b264",checklistId:"8b479656-8cde-4bff-9c51-d5eca369bc76",fullName:"dsad",year:"2021-01-01T00:00:00",quarter:"2021-Q3",versions:1},{id:"01000f98-6470-440a-a833-95b199ab1f7a",checklistId:"039f2584-1ca5-4ee3-b46f-cdf1887af7f6",fullName:"NEWQ1",year:"2021-01-01T00:00:00",quarter:"2021-Q1",versions:2}]};
const result = {
isExternalId: obj.isExternalId
};
result.modules = obj.modules.map((el, i) => ({
...el,
...obj.activatedItems[i],
...obj.quarterItems[i]
}));
console.log(result);
Goal:
Im trying to make an array of objetcs including 3 informations: id, title and imageUri. But when i try to get the imageUri value from firebase(an image download URL from firebase) to download this image in another component, the iteration of forEach freezes. Thank you for your time :)
Warning:[Unhandled promise rejection: TypeError: JSON.stringify cannot serialize cyclic structures.]
observation: When i remove the firebase part imageUri: firebase..., the whole thing works!
the function:
processData = ( data ) => {
console.log('---------data received from loadData(Main.js:70)--------\n', data)
var localProcessedData = [];
Object.entries(data).forEach( ([key, value]) => {
var event = {
id: key,
title: Object.getOwnPropertyDescriptor(value, "eventTitle").value,
imageUri: firebase.storage().ref('events/active/' + key + '/image').getDownloadURL()
}
localProcessedData.push(event);
})
this.setState({
processedData: localProcessedData,
eventsDataIsLoaded: true,
})
}
The type of params the function recieve:
Object {
"-M-I83aV9t1fezOsBn17": Object {
"active": true,
"created": "2020-02-05T02:18:30.772Z",
"description": "Olimpiadas Inter Atletica",
"eventTitle": "oia",
"location": "Uberlandia",
"owner": "p87xn6x8DZTwb6qyTadhkk3UxJV2",
"price": "130",
"startDate": "15",
"time": "14",
"updated": "2020-02-05T02:18:30.772Z",
},
"-M-KlUH-zQhnIhb6wMH8": Object {
"active": true,
"created": "2020-02-05T14:34:20.399Z",
"description": "Cia 2020",
"eventTitle": "Cia",
"location": "Uberlandia",
"owner": "p87xn6x8DZTwb6qyTadhkk3UxJV2",
"price": "130340",
"startDate": "15",
"time": "14",
"updated": "2020-02-05T14:34:20.399Z",
}
}
Expected:
My goal is to transform that whole data in an array like this:
Array [
Object {
"id": "-M-I83aV9t1fezOsBn17",
"title": "oia",
"imageUri": "image url from firebase"
},
Object {
"id": "-M-KlUH-zQhnIhb6wMH8",
"title": "Cia",
"imageUri": "image url from firebase"
}
]
Based on firebase documentation. FIrebase Storage getDownloadUrl is a promise
https://firebase.google.com/docs/reference/js/firebase.storage.Reference.html#get-downloadurl
solution is to implement an async/await
async processData = ( data ) => {
console.log('---------data received from loadData(Main.js:70)--------\n', data)
var localProcessedData = [];
Object.entries(data).forEach( async([key, value]) => {
var event = {
id: key,
title: Object.getOwnPropertyDescriptor(value, "eventTitle").value,
imageUri: await firebase.storage().ref('events/active/' + key + '/image').getDownloadURL()
}
localProcessedData.push(event);
})
this.setState({
processedData: localProcessedData,
eventsDataIsLoaded: true,
})
}
this code is not yet tested.
I have getting some issue in map program in node.js. I am trying to use MAP into node.js program and I am not getting value.I have write some code to use map however I think it not working as its not go into the loop to fetch the key-value.
Please find below program
async CreateProduceMVPRateAsset(data, callback) {
var ProducePRICE = {};
var MVPPRICE =[];
var MVPPRICE_BS ={};
var MVPPRICE_LB ={};
//var ASKINGPRICE= {}// put all the things which need to go to blockchain
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
console.log('Data', data);
console.log('Username', data.username);
var PRODUCENAME = data.PRODUCE
console.log('PRODUCENAME', PRODUCENAME);
var COUNTRY = data.COUNTRY;
console.log('COUNTRY', COUNTRY);
var STATE = data.STATE;
console.log('STATE', STATE);
var MVPRATES = data.MVPRATES;
console.log('MVPRATERATE', MVPRATES);
const MVPRATE = new Map(MVPRATES);
// program could not go inside the for loop
for (const [k, v] of MVPRATE.entries()) {
console.log("Inside map", k, v)
MVPPRICE = v.RATE // should go in MVPPRICE
var Value = MVPPRICE[0].value // want to get first element value from MVPPRICE array
console.log('Value', Value);
var value_lb = Value/40;
console.log('value_lb', value_lb);
value_lb = Number((value_lb).toFixed(4));
console.log('If the value of BS provided controller come here');
MVPPRICE_LB.Value = value_lb
MVPPRICE_LB.QuantityUnit = 'LB'
MVPPRICE_LB.uidisplay = false
MVPPRICE_LB.CurrencyUnit = 'USD'
MVPPRICE.push(MVPPRICE_LB);
ProducePRICE.MVPPRICE = MVPPRICE
console.log('MVPPRICE',MVPPRICE);
console.log('ProducePRICE',ProducePRICE);
// mvpprice.totalPrice = totalPrice;
console.log('for pricing',totalPrice);
// ProducePRICE.VARIETY = VARIETY;
ProducePRICE.PRODUCENAME = PRODUCENAME;
ProducePRICE.STATE = STATE;
ProducePRICE.COUNTRY = COUNTRY;
}
JSON structure which I am sending using postman
{
"username": "admin2",
"PRODUCE": "Apple",
"STATE": "MI",
"COUNTRY": "US",
"MVPRATES": {
"fuji": {
"VARIETY": "fuji",
"RATE": [
{
"UNIT": "Bussel",
"CURRENCY": "USD",
"VALUE": 10.25,
"UIDISPLAY": true
}
]
},
"gala": {
"VARIETY": "gala",
"RATE": [
{
"UNIT": "Bussel",
"CURRENCY": "USD",
"VALUE": 10.25,
"UIDISPLAY": true
}
]
}
}
}
Output which I am getting:
Seems like you may want to do the following, this creates a Map with two entries, fuji and gala
const MVPRATES = {
"fuji": {
"VARIETY": "fuji",
"RATE": [{
"UNIT": "Bussel",
"CURRENCY": "USD",
"VALUE": 10.25,
"UIDISPLAY": true
}]
},
"gala": {
"VARIETY": "gala",
"RATE": [{
"UNIT": "Bussel",
"CURRENCY": "USD",
"VALUE": 10.25,
"UIDISPLAY": true
}]
}
}
const MVPRATE = new Map(Object.entries(MVPRATES));
for (const [k, v] of MVPRATE.entries()) {
console.log("Inside map", k, v)
}
Though, the need for Map is still unclear, as you can achieve the above with
const MVPRATES = {
"fuji": {
"VARIETY": "fuji",
"RATE": [{
"UNIT": "Bussel",
"CURRENCY": "USD",
"VALUE": 10.25,
"UIDISPLAY": true
}]
},
"gala": {
"VARIETY": "gala",
"RATE": [{
"UNIT": "Bussel",
"CURRENCY": "USD",
"VALUE": 10.25,
"UIDISPLAY": true
}]
}
}
for (const [k, v] of Object.entries(MVPRATES)) {
console.log("Inside map", k, v)
}