How to assign grabbed data to outer scope variable in JavaScript restangular - javascript

I'm were had troble to fetching plain objects from database using restangular and i solved it by using restangular plain() method on fetched data. but now i'm having a trouble on assigning that data to outer scope variable. demo code-
i have load all function -
function loadAll() {
var feelings = [];
Restangular.all('feelings').getList().then(function(data) {
angular.forEach(data.plain(), function(feeling) {
feelings.push(feeling);
})
})
console.log(feelings) // shows empty array :( , how to sole this issue
//----------------------------------------
// i wants my data like this to be returned
var feelings = [{
feeling_name: 'best',
view_count: 50
}, {
feeling_name: 'funny',
view_count: 150
}, {
feeling_name: 'angry',
view_count: 40
}, {
feeling_name: 'loved',
view_count: 42
}]
//-----------------------------------------------
return feelings.map(function(feeling) {
feeling.value = feeling.feeling_name.toLowerCase();
return feeling;
});
}

Related

How to excute a task asynchronously in node.js?

I was trying to execute multiple tasks asynchronously in node.js then save the return value into an object while putting all the tasks(promises) in a promise.all([]) but it doesn't seem to be working.
//A really minified function for convienince which sends a req to an api then
//assigns the response to the object that is passed in as a parameter
async function getAssessmentData(cookie, params,refObj){
const result = await fetch(
`https://www.sampleURL.com?` +
new URLSearchParams({
academicYearId: params.academic_year,
semesterId: params.semester,
courseId: params.course,
}),
);
//Assign the response to the object inside the parameter which i should have reference of
refObj = await result.json();
}
//I stringified the output object to display it here (consider it as a Javascript object)
let output= [
{
"meta":{
"academic_year":"2020/21",
"year":"Year III",
"semester":"One"
},
"assessment":[
{
"course_grade":"A",
"course_link_data":{
"academic_year":"f4c351be-8ed7-4197-9768-25d6e67c063e",
"semester":"11111111-1111-1111-1111-111111111111",
"course":"73adfaa1-0666-46a5-a2c4-3b0970d9025d"
},
"course_assessment":{
"assessments":[
],
"total":null
}
},
{
"course_grade":"B",
"course_link_data":{
"academic_year":"f4c351be-8ed7-4197-9768-25d6e67c063e",
"semester":"11111111-1111-1111-1111-111111111111",
"course":"6ab5fbe9-086e-46c8-b115-d0d9f19a98a3"
},
"course_assessment":{
"assessments":[
],
"total":null
}
}
],
"footer":{
"sgp":"0",
"sgpa":"0",
"cgp":"0",
"cgpa":"0",
"academicstatus":"Not determined yet!"
}
},
{
"meta":{
"academic_year":"2020/21",
"year":"Year III",
"semester":"One"
},
"assessment":[
{
"course_grade":"A",
"course_link_data":{
"academic_year":"f4c351be-8ed7-4197-9768-25d6e67c063e",
"semester":"11111111-1111-1111-1111-111111111111",
"course":"73adfaa1-0666-46a5-a2c4-3b0970d9025d"
},
"course_assessment":{
"assessments":[
],
"total":null
}
},
{
"course_grade":"B",
"course_link_data":{
"academic_year":"f4c351be-8ed7-4197-9768-25d6e67c063e",
"semester":"11111111-1111-1111-1111-111111111111",
"course":"6ab5fbe9-086e-46c8-b115-d0d9f19a98a3"
},
"course_assessment":{
"assessments":[
],
"total":null
}
}
],
"footer":{
"sgp":"0",
"sgpa":"0",
"cgp":"0",
"cgpa":"0",
"academicstatus":"Not determined yet!"
}
}
]
promiseList = [];
for (const element of output) {
for (const elementNested of element.assessment) {
promiseList.push(
getAssessmentData(identityCookie,elementNested.course_link_data,elementNested.course_assessment);
)
}
}
await Promise.all(promiseList);
console.log(JSON.stringify(output))
The course_link_data object is not changing.
From some debugging, I've found out that the getAssesmentData function is working correctly but I expect the problem is that the elementNested.course_assessment object I'm passing to the function from the loop is not from the "output" object.
since I'm going to send around 50 requests at once I thought I would do them asynchronously, is there a way to achieve this?

Setting the property of one specific key in an object in a reduce is setting it for all properties

Okay, I have literally no idea whats going on here. I'm assuming its some kind of reference issue? But I dont know how to get around it or whats causing it.
To sum it up, I have a list of objects, as well as an object that gets prepopulated to make sure I have data for all keys in the object.
I need to iterate over this list of objects, and by using the timeframeId in the metadata object, and the id in the data object, I want to assign the entire data object to the corresponding timeframeId and id hierarchy in the prepopulated object.
For some reason, all data properties are being overwritten to whatever the last row data is.
I've linked a repl so you can see for yourself: https://repl.it/#ThomasVermeers1/UnwrittenNoisyFirm#index.js
But my code is as follows:
const buildSegmentsFromRows = (rows, timeframeMetadata, defaultSegmentData) => {
// Prepopulate object to make sure every timeframe has a 'hello' key in it with some data
const emptySegments = timeframeMetadata.reduce((segmentMap, metadata) => {
segmentMap[metadata.timeframeId] = {
metadata,
segments: defaultSegmentData,
};
return segmentMap;
}, {});
// Now simply just loop over the rows, and set [row.metadata.timeframeId].segments[row.data.id] to row.data
const segments = rows.reduce((partialSegments, row) => {
const { timeframeId } = row.metadata;
const { id } = row.data;
/**
* This is the line where everything goes wrong
*/
partialSegments[timeframeId].segments[id] = row.data;
return partialSegments;
}, emptySegments);
return segments;
};
const rows = [
{
metadata: { timeframeId: '20202_01' },
data: {
'id': 'hello', 'value': 15
}
},
{
metadata: { timeframeId: '20202_02' },
data: {
'id': 'hello', 'value': 10
}
}
]
const timeframemetadata = [
{ timeframeId: '20202_01'},
{ timeframeId: '20202_02'}
]
const defaultSegmentData = {
'hello': {
'id': 'hello',
}
}
console.log(JSON.stringify(buildSegmentsFromRows(rows, timeframemetadata, defaultSegmentData), null, 2))
I'm expecting the end result to be:
{
"20202_01": {
"metadata": {
"timeframeId": "20202_01"
},
"segments": {
"hello": {
"id": "hello",
"value": 15
}
}
},
"20202_02": {
"metadata": {
"timeframeId": "20202_02"
},
"segments": {
"hello": {
"id": "hello",
"value": 10
}
}
}
}
But instead, value is getting set to 10 in all instances. I'm thinking its because we're setting the property to row.data, which is a reference, and gets updated on every call? But I'm at a complete loss here.
The problem is that you are referring to the same object for every segments in the list.
Therefore, changing the value of segments[id] will update defaultSegmentData, causing every reference to defaultSegmentData to change as well.
const emptySegments = timeframeMetadata.reduce((segmentMap, metadata) => {
segmentMap[metadata.timeframeId] = {
metadata,
segments: defaultSegmentData, // Everything goes wrong here.
};
return segmentMap;
}, {});
A simple solution to this problem is to avoid using the same reference to the object when creating the segmentMap:
const emptySegments = timeframeMetadata.reduce((segmentMap, metadata) => {
segmentMap[metadata.timeframeId] = {
metadata,
/** Or whatever default value you want.
* Just make sure to create a new instance of it for each call.
*/
segments: {},
};
return segmentMap;
}, {});

How do I merge two downloaded arrays into a single JSON array?

I'm pretty new to learning to code. So i might get a lot of basics wrong.
Basically i am downloading API content from two different accounts via request-promise and want to merge them into a bigger array. I'm struggling with escaping my local data from the request-promise function and also combining it with the second array
Here's what i got so far:
//request the site and do some stuff with the data
rp(rpOptions)
.then(function (parsedBody) {
let incomingData1 = (parsedBody); //turning data into a value to change it a little
incomingData1.forEach((incomingData1) => {incomingData1.yearsRetired = 0}); //to add a new property
incomingData1 = JSON.stringify(parsedBody, ["favFood", "age", "work", "yearsRetired"], 2); //to filter only relevant properties into a JSON thing (i eventually want to save it to a txt file)
});
i'd then do the same for the second account and then try to get that data outside of the function and merge it into a single array so that it looks like this:
{
"first_account_name": {
"individual1": {
"favFood": 'fries',
"age": 23,
"work": 'astronaut'
"yearsRetired": 0
},
"individual2": {
"favFood": 'banana',
"age": 55,
"work": 'zookeeper'
"yearsRetired": 0
{
...
}
},
"second_account_name": { ... }
"individual6": {
"favFood": 'apple',
"age": 49,
"work": 'dinosaur'
"yearsRetired": 0
"individual7": {
"favFood": 'sausage',
"age": 33,
"work": 'doctor'
"yearsRetired": 0
{
...
}
how do i get my data into a variable outside of rp? and how do i set it up so that it ends up like a nested array?
Thanks a lot and sorry for being confusing :P
What you are looking for is a global array that gets data pushed into it on every Promise request called right. So firstly, create a simple array and place it on top of the page or if you are using a class just insert it into the respective fields.
Let accountDetails = [];
Next, inside then function call this variable like so,
rp(rpOptions)
.then(function (parsedBody) {
let incomingData1 = (parsedBody);
incomingData1.forEach((incomingData1) => {incomingData1.yearsRetired = 0});
incomingData1 = JSON.stringify(parsedBody, ["favFood", "age", "work", "yearsRetired"], 2);
accountDetails.push({
"individual1" : incomingData1
})
});
If you're using ES6
const processData = (data) => {
return data.map((item) => ({
favFood: item.favFood,
age: item.age,
work: item.work,
yearsRetired: 0
}))
}
// any value returned by then will be wrapped in promise
// and can be `await` ed
// you can also use
// const [ data1, data2 ] = await Promise.all([
// rp(requestOption1).then(data => processData(data)),
// rp(requestOption2).then(data => processData(data))
// ])
// if you want it to be executed parallely
const data1 = await rp(requestOption1).then(data => processData(data));
const data2 = await rp(requestOption2).then(data => processData(data));
const mergedData = [
...data1,
...data2
];
If you don't have async await
const processData = (data) => {
return data.map((item) => ({
favFood: item.favFood,
age: item.age,
work: item.work,
yearsRetired: 0
}))
}
Promise.all(
rp(requestOption1).then(data => processData(data)),
rp(requestOption2).then(data => processData(data))
).then(results => {
const mergedData = results.reduce((collection, result) => {
return collection.concat(result);
}, []);
})
Note:
I wrote the function name processData because I don't know what is being processed. I suggest you to be more specific on the function name. (e.g. what it does)

Postgres Javascript Promise isn't returning modified result

I need some help understanding Javascript promises. I'm using postgres and I want a function that will take an array of objects as per the example below
[ { airlineName: 'NZ',
{ airlineName: 'TN']
and I want it to return the array as below
[ { airlineName: { iatacode: 'NZ', airlineName: 'Air New Zealand' },
{ airlineName: { iatacode: 'TN', airlineName: 'Air Tahiti Nui' }]
For simplicity I have simplified the query here, however the query works fine,
The problem arises if I console log the array I get the results in the correct format above, however if I try and return the statement I get undefined passed back!
Any ideas?
exports.extractAirlineName = (flightInfo) => {
db.many("SELECT airline_name FROM airline_info WHERE iatacode IN 'NZ', 'TN'")
.then(airline => {
flightInfo.forEach((flight, index) => {
flight.airlineName = {
iatacode: flight.airlineName,
airlineName: airline[index].airline_name
};
// this shows the correctly populated object
console.log(flightInfo);
//this just returns undefined
return flightInfo;
});
});
};

access array member of type object in javascript

I have been trying to access array member from an Array (data_array).My variable data_array is part of json something similar to code below. The code below is not the actual code. The actual code is coming in play when i am trying to create a React component. I can paste the complete React component but it would contain some unnecessary information. So i thought i would add some mock example. Apologies if it misled people. Currently i was hoping to get some hints on what could possibly go wrong in such scenario?
:
data: {
"name": "Arjun",
"records" : [
{
"value": 3
},
{
"value": 6
},
{
"value":7
}
]
}
var data_array = data.records
console.log(data_array) -> Array[3]
console.log(data_array[0]) -> It displays Uncaught TypeError: Cannot read property '0' of undefined
console.log(typeof data_array) -> Object.
What's confusing to me is my first output as it says its an Array.I am fairly new to javascript. So maybe i am missing something. Any help would be appreciated.
Edit: This would still be missing a nested React Component but it would be of no use in this case. I am calling the nested component Foo for now
var React = require('react'),
Router = require('react-router'),
mui = require('material-ui'),
Foo = require('./foo.jsx');
var TempReact = React.createClass({
mixins: [Router.Navigation],
getInitialState: function() {
return {
data: {}
};
},
componentDidMount: function() {
// Do a web request here to actually get the data from the backend API
// this.setState({
// });
// For now, load our fake data
this._loadFakeData();
},
render: function() {
//console.log(this.state.data)
for(var record in this.state.data.records) {
console.log(record.Value);
}
//console.log(this.state.data["records"][0]["Value"])
return (
<div>
<p>^ That will still say , since the header up there is decided by temp-page.jsx, which is
based on the route</p>
<br/>
<p>We've loaded the fake data into our component's state, and here's proof:</p>
{this.state.data.name}
<br/>
<br/>
<Foo name={["temp1",this.state.data.records,"green"]}/>
</div>
);
},
_loadFakeData: function() {
this.setState({
data: {
"name": "Arjun",
"records" : [
{
"Value": 6
},
{
"Value": 7
},
{
"Value": 8
}
]
}
});
}
});
module.exports = TempReact;
Arrays are typeof Object. They're just an object with some fancy stuff going on.
The following example works:
var data = {
"name": "Arjun",
"records" : [
{
"value": 3
},
{
"value": 6
},
{
"value":7
}
]
}
var data_array = data.records
console.log(data_array[0]) // Object {value: 3}
This error happens when you do something like this:
var data = {};
var data_array = data.array; // data.array is undefined and subsequently data_array.
console.log(data_array[0]); // Throws: Uncaught TypeError: Cannot read property '0' of undefined
You're not far off lets say you store this object in a variable called jsonData just for an example :
var jsonData = {
data: {
"name": "Arjun",
"records" : [
{
"value": 3
},
{
"value": 6
},
{
"value":7
}
]
}
}
You'll need to access the variable > property > nested property , then specify the index like so :
var data_array = jsonData.data;
console.log(data_array.records[0].value)
--> should log 3
EXAMPLE HERE: http://codepen.io/theConstructor/pen/wGdpjq
So the problem might have been with SetState() in React, I was able to access the objects by pushing them first in an empty array:
var varArr = new Array();
for(key in this.state.data.records) {
if(this.state.data.records.hasOwnProperty(key)) {
var value = this.state.data.records[key];
varArr.push(value);
}
}
data_array is an Array. data.records in an Array. What are you expecting to see?

Categories