I'm working on an app where I need to pass an array of strings to a backend service something like
const ids = [];
for (let i = 0; i < pIds.length; i++) {
ids.push(pIds[i].id);
}
// pIds is an array of objects [{id: 2, name: 'dd'}]
this.webClient = new Frisbee({
baseURI: `${Secrets.url_host}/api/v1`,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
getData({ continuation = 1, q = '', ids = '' }) {
return this.webClient.get('/whatever', {
body: {
'platform_ids': ids,
},
}).then(getContent);
}
after running this code if get an array of ids [2,3] for example
but when I pass it to the backend (ruby on rails ) it arrive like that
[{"0"=>"1", "1"=>"2"}]
What can I do to get it as ["1", "2"]? I've tried many solutions but nothing works.
I couldn't solve it , so i changed my backend to accept string with "," and parsing it to array in the backend .
for example
const ids = {id: 3, id: 4};
const idsForBackend = ids.map(id => id.id).join();
Related
I need to make a list of objects based on combined data from 2 arrays, one comes from a localStorage and the second one from Django backend. First of all objects from localStorage are displayed by showCart() function
export const showCart = () => {
if (typeof window !== undefined) {
if (localStorage.getItem("cart")) {
return JSON.parse(localStorage.getItem("cart"));
};
};
};
it returns data in this format: FE: { id: 1, amount: 7, size: "L", product: 1 }. product is the Foreign Key needed to match data from other array.
The second array comes form a backend and it is feched by getAllProducts() function
export const getAllProducts = () => {
return fetch(`${url}/products/`, {method: "GET"})
.then((response) => {
return response.json();
})
.catch((error) => console.log(error))
};
It returns data in this format: FE { name: "Red", id: 3, price: 33, image:"some-url"}
ββ
Now I need to create another list of objects by merging then by product of an object in first array with id of an object from the second one. The objects in the third array need to contain amount and size from first array as well as name, price and image from the second one. In the end I want to store it in useState().
This is what I came up with, I guess my code stops working arter first for loop:
const [cart, setCart] = useState([]);
const CheckAnonymousCart = () => {
getAllProducts()
.then((data) => {
const localCart = showCart();
var products = [];
for (let i = 0; i < localCart.lenght; i++) {
for (let y = 0; y < data.lenght; y++) {
if (localCart[i].product === data[y].id) {
console.log(localCart[i].product, data[y].id)
const item = {
name: data[y].name,
price: data[y].price,
image: data[y].image,
amount: localCart[i].amount,
size: localCart[i].size,
}
products.push(item)
break;
}
}
}
setCart(products);
})
.catch((error) => console.log(error))
};
ββAny thoughts?
In addition to Jacob's comment, you probably want to avoid FETCH'ing all products from the DB, because it requires more DB resources, most of the info is not required, and it makes the for-loop take longer to JOIN both lists.
Ideally, you would use a parameterized query like so:
return fetch(`${url}/products/?id=1&id=2&id=3`, {method: "GET"})
Where ?id=1&id=2&id=3 are a subset of the product IDs that you're retrieving.
Note: You will also want to sanitize/validate the product IDs in localStorage, because the data can be modified by the end-user, which is a potential attack vector by malicious users.
The problem could simply be the typo from the for loop conditions, but you can also accomplish this more succinctly using the JS ES6 methods:
const products = localCart.map(item => {
const match = data.find(x => x.id === item.product);
return {
amount,
size,
name: match?.name,
price: match?.price,
image: match?.image
}
});
I have an API that I am calling to return a query. This query's format cannot be changed to be easier to manipulate. It has a nested array within it that I need to associate with the data from the higher levels.
Specifically, I am trying to pull the higher level id field and and the "value" field within "column_values" and associate them with one another preferably within a new array. I feel like the answer is here but I just can't grasp how to pull the data in the correct format and associate it together. Most of the comment lines can probably be ignored, they are my other attempts at making the syntax work correctly. Sorry about the mess. I'm really new to this.
const axios = require('axios')
const body = {
query: ` query {boards(ids:307027197) {name, items {name id column_values(ids:lockbox_) {title id value text}}}} `,
}
console.log("Requesting Query....");
function getApi (callback){
setTimeout(function() {axios.post(`https://api.monday.com/v2`, body, {
headers: {
MY_API_KEY_DATA
},
})
.catch(err => {
console.error(err.data)
})
.then(res => {
var queried = res
var array = queried.data.data.boards[0].items
//console.log(queried)
//console.log(array)
console.log(array.length)
//console.log("Total Items:", array.length)
var i;
for (i = 0; i < array.length; i++){
callback(queried.data.data.boards[0].items)
//callback([(queried.data.data.boards[0].items[i].column_values[0])])
}
}, 0);
})
};
getApi(callback => {
console.log(callback)
//console.log(parsed)
//output for above
//{"name":"address","id":"1234","column_values":
//[{"title":"Lockbox#","id":"lockbox_","value":"\"31368720\"","text":"31368720"}]}
//console.log(JSON.parse(parsed))
//output for above
//[
// {
// name: 'address',
// id: '353428429',
// column_values: [ [Object] ]
// }
//]
});
setTimeout(function() {
console.log("Query Returned")},1000);
From your data, column_values is an array with objects in it. For an array, you will have to access it with the key. For your case, if your data is like
var data = {
"name":"address",
"id":"1234",
"column_values": [{"title":"Lockbox#","id":"lockbox_","value":"\"31368720\"","text":"31368720"}]
}
You can access the id of column_values as data.column_values[0].id
I have been trying to filter the results of an API call based on my "note" value. I've been building it on Zapier and the call works but I cannot seem to find a way to make a filter function do its job (so if I replace line 19-23 with return results; then it gives me all orders from the api call). I've poured over every stack document I could find but they all end with the error result.filter not found, or a bargle error (generic error in Zapier).
const options = {
url: `https://mystorename.myshopify.com/admin/orders.json?`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
params: {
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
var results = z.JSON.parse(response.content);
var queryItem = "555-5555"
const filteredOrders = results.orders.filter(item => item.note === queryItem);
return filteredOrders;
});
And this is an example of my current output with return results; and no filter:
{
"orders": [
{
"note": "555-5555",
"subtotal_price": "1.00"
},
{
"note": "555-6666",
"subtotal_price": "2.00"
}
]
}
Again the goal is to filter by the value in the "note" key. So if my filter input is 555-5555 then it should return all information for that item only. I did try to use an if statement for return, stringify instead of parse, covert to array...all with needed code, but regardless of the format I find filter does not work or nothing is returned. Going to keep working on it, so if I happen to find the answer I will post that, but at this point I feel stuck.
You are trying to use the method filter in a object but filter is only available in an array so you should try to call filter in the orders array.
let results = {
"orders": [
{
"note": "555-5555",
"subtotal_price": "1.00"
},
{
"note": "555-6666",
"subtotal_price": "2.00"
}
]
}
let queryItem = "555-5555";
let newArray = results.orders.filter(function (item) {
return item.note == queryItem
})
console.log(newArray)
Updated to contain a real http call:
const url = 'http://www.mocky.io/v2/5d9466142f000058008ff6b7'
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
}
const response = await fetch(url, options)
const results = await response.json()
const queryItem = "555-5555"
const filteredOrders = results.orders.filter(item => item.note === queryItem)
console.log(filteredOrders)
You are trying to filter on results, but according to your output, you should be filtering on results.orders.
const filteredOrders = results.orders.filter(item => item.note === queryItem);
Are you getting all the orders back (all the orders with the specified filter value)?
I realized I wasn't getting back all orders and this did the trick:
`https://mystorename.myshopify.com/admin/orders.json?status=any`
Alternatively, you can query the orders with that specific note:
`https://mystorename.myshopify.com/admin/orders.json?status=any¬e=` + queryItem
I am chaining a bunch of axios get request to different endpoints of an API and I'm trying to create an array like this from the data (simplified):
[
{
name: "John",
id: 1,
gender: "male"
},
{
name: "Anna",
id: 2,
gender: "female"
},
]
In one of the requests I retrieve each person's name and id in an array like this:
[
{
name: "John",
id: 1
},
{
name: "Anna",
id: 2
},
]
Now I only need to get their gender by sending each persons's id in two separate requests to an endpoint.
I have spent hours trying to construct the array at the top with push() and then() but I just can't get it right.
How do I go about this?
I'm chaining the axios requests like this btw:
axios.get('api/' + endpoint1]).then(response => {
axios.get('api/' + endpoint2).then(response => {
axios.get('api/' + endpoint3).then(response => {
// and so on...
});
});
});
UPDATE 1:
I feel like I didn't explain the problem properly. This is what my code looks like right now, starting from the last promise. How can I change it in order to get the array at the top of my question?
.then(response => {
people= response.data; // Array of people including their name id (not their gender though)
for (var key in people) {
var person = {};
person["name"] = people[key].node.name;
person["id"] = people[key].node.id;
finalArray.push(person);
axios.get('api/' + endpoint3, { // Endpoint for getting a persons gender from id
params: {
personId: person.id
}
}).then(response => {
// I don't know what to do here...
});
}
console.log(finalArray); // Gives me an array of objects without "gender".
});
UPDATE 2:
Thanks alot for your answers!
I've combined some of your solutions and this is how my real code looks right now. The requests to http://api.ntjp.se/coop/api/v1/serviceProducers.json are not sent. Why?
I also don't want to keep the whole objects within the cooperations response array before calling http://api.ntjp.se/coop/api/v1/serviceProducers.json. I just want to save two specific key/value pairs from each object. These two key/value pairs are both within an object called "serviceContract" within in each response object. How do I save them?
<html>
<head>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script>
getConnectionStatusData();
async function getConnectionStatusData() {
let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
params: {
namespace: "crm:scheduling"
}
});
serviceDomainId = serviceDomains.data[0].id;
let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
params: {
platform: "NTJP",
environment: "PROD"
}
});
connectionPointId = connectionPoints.data[0].id;
let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
params: {
logicalAdress: "SE2321000016-167N",
serviceConsumerHSAId: "SE2321000016-92V4",
connectionPointId: connectionPointId
}
});
logicalAddressId = logicalAddresss.data[0].id;
let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
params: {
connectionPointId: connectionPointId,
logicalAddressId: logicalAddressId
}
});
consumer = serviceConsumers.data.filter(obj => {
return obj.hsaId === "SE2321000016-92V4"
});
serviceConsumerId = consumer[0].id;
let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
params: {
connectionPointId: connectionPointId,
logicalAddressId: logicalAddressId,
serviceDomainId: serviceDomainId,
serviceConsumerId: serviceConsumerId,
include: "serviceContract"
}
});
for(var idx in cooperations.data) {
var data = async () => { return await axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
params: {
connectionPointId: connectionPointId,
logicalAddressId: logicalAddressId,
serviceDomainId: serviceDomainId,
serviceConsumerId: serviceConsumerId,
serviceContractId: cooperations.data[idx].serviceContract.id
}
}) }
cooperations.data[idx].producerDescription = data.description;
cooperations.data[idx].producerHSAId = data.hsaId;
}
console.log(cooperations.data);
}
</script>
</body>
UPDATE 3
I finally made it work but why do I have to reference to the data like response.data[0].description when I push it into finalResult in the end? I mean, why doesn't just response.data.description work, as it does for #Cold Cerberus?
Other than that, is my code ok in or have I done something wrong?
Thanks guys!
<html>
<head>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script>
getConnectionStatusData();
async function getConnectionStatusData() {
let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
params: {
namespace: "crm:scheduling"
}
});
serviceDomainId = serviceDomains.data[0].id;
let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
params: {
platform: "NTJP",
environment: "PROD"
}
});
connectionPointId = connectionPoints.data[0].id;
let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
params: {
logicalAdress: "SE2321000016-167N",
serviceConsumerHSAId: "SE2321000016-92V4",
connectionPointId: connectionPointId
}
});
logicalAddressId = logicalAddresss.data[0].id;
let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
params: {
connectionPointId: connectionPointId,
logicalAddressId: logicalAddressId
}
});
consumer = serviceConsumers.data.filter(obj => {
return obj.hsaId === "SE2321000016-92V4"
});
serviceConsumerId = consumer[0].id;
let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
params: {
connectionPointId: connectionPointId,
logicalAddressId: logicalAddressId,
serviceDomainId: serviceDomainId,
serviceConsumerId: serviceConsumerId,
include: "serviceContract"
}
});
var finalData = [];
cooperations.data.forEach(function(cooperation) {
axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
params: {
connectionPointId: connectionPointId,
logicalAddressId: logicalAddressId,
serviceDomainId: serviceDomainId,
serviceConsumerId: serviceConsumerId,
serviceContractId: cooperation.serviceContract.id
}
}).then(response => {
finalData.push({serviceContract: cooperation.serviceContract.namespace, serviceProducerDescription: response.data[0].description, serviceProducerHSAId: response.data[0].hsaId});
});
});
console.log(finalData);
}
</script>
</body>
I'm not quite sure of your specific problem. But assuming that what you mean is you have two endpoints, first is the one that returns an array of object (lets call it 'getPeopleArray'):
[
{
name: "John",
id: 1
},
{
name: "Anna",
id: 2
}
]
and second endpoint returns the gender of the given id (lets call it 'getGender' with one param id), .push will not do the job for you.
Your problem can be solved with something like this:
let peopleArray = [];
axios.get('api/' + 'getPeopleArray').then(people => {
peopleArray = people;
people.forEach((person, index) => {
axios.get('api/' + 'getGender?id='.concat(person.id.toString()))
.then(gender => {
peopleArray[index].gender = gender;
});
});
});
First is you save the returned array of your first request and then you will have to loop through each object in that array to get and assign their genders from your second endpoint using the index argument of your [].forEach(callbackfn). As long as there is no manipulation with peopleArray during or before all requests are finished, the index will be correct.
Update 2:
In response to your question in the comments "why .push doesn't work?", I decided to make another approach If you want to end your algorithm with using .push and go without tracking indexes.
let peopleArray = [];
axios.get('api/' + 'getPeopleArray').then(people => {
people.forEach((person) => {
axios.get('api/' + 'getGender?id='.concat(person.id.toString()))
.then(gender => {
peopleArray.push({id: person.id, name: person.name, gender, gender});
});
});
});
This way you will only push your object to your collection peopleArray when its respective gender is also fetched. This will also eliminate having to use .map (as suggested in the comments) for storing only the individual object's properties you desire to keep since you pushed a new structured object on line peopleArray.push({id: person.id, name: person.name, gender, gender});.
I do not like to read chained promises and prefer to use async/await instead. You could get your list first and then loop through that list with a map and request the gender for each name. Remember that you have to wait for all promises to resolve inside your map before you can proceed.
const axios = require('axios');
async function getPeople() {
let firstResult = await axios.get('api/path/endpoint1');
// firstResult = [{name: "John", id: 1}, {name: "Anna", id: 2}]
let updatedResult = firstResult.map(async item => {
let people = await axios.get('api/path/endpoint2' + item.name); // or however your endpoint is designed
// people = {name: "John", id: 1, gender: male}
item.gender = people.gender;
return item;
});
// updatedResult = undefined
Promise.all(updatedResult)
.then(finalResult => console.log(finalResult));
// [{name: "John", id: 1, gender: male}, {name: "Anna", id: 2, gender: female}]
}
You can use async/awaits and reassign gender key to first endpoint data ...
var users;
axios.get('api/' + endpoint1]).then(response => {
users = response; // assume all user id list
for(var idx in users) {
var data = async () => { return await axios.get('api/' + users[idx].id) } //get gender api by user id
users[idx].gender = data.gender; //create gender key value
}
console.log(users);
});
I have an object myObject like this
0:
timestamp: 1525879470
name: "testing"
lastname: "testingdone"
1:
timestamp: 1525879470
name: "testing2"
lastname: "testingdone2"
I am looking for a way to convert it to csv nicely like this
timestamp,name,lastname
1525879470,testing,testingdone
1525879470,testing2,testingdone2
Good news is I can extract the header
var headers = Object.keys(myObject.reduce(function (result, obj) {
return Object.assign(result, obj);
}, {}));
The headers var will give me an array of headers like
Array(3): timestamp, name, lastname
I am just looking to extract the values from the object maybe in an array like header, and then finally convert it into CSV as above. I tried using array map but for some reason I am not able to figure it out
If that is array of objects you can first get header and then values and create string from that.
const data = [ {timestamp: 1525879470,name: "testing",lastname: "testingdone"
}, {timestamp: 1525879470,name: "testing2",lastname: "testingdone2"}]
let csv = '';
let header = Object.keys(data[0]).join(',');
let values = data.map(o => Object.values(o).join(',')).join('\n');
csv += header + '\n' + values;
console.log(csv)
A more simplified approach based on the examples above
// Sample data - two columns, three rows:
const data = [
{code: 'HK', name: 'Hong Kong'},
{code: 'KLN', name: 'Kowloon'},
{code: 'NT', name: 'New Territories'},
];
// Transform an array of objects into a CSV string
const csv = function(data) {
// Setup header from object keys
const header = Object.keys(data[0]).join(",");
// Setup values from object values
const values = data.map(item => Object.values(item).join(","));
// Concat header and values with a linebreak
const csv = [header, ...values].join("\n");
return csv;
};
// Setup file
const file = csv(data)
console.log({ file })
If that thing (myObject) is a JavaScript object, you can serialize it in array chunks using destructuring and then join them in a string using Array#reduce:
const data = {
'0': {
timestamp: 1525879470,
name: "testing",
lastname: "testingdone"
},
'1': {
timestamp: 1525879470,
name: "testing2",
lastname: "testingdone2"
}
};
const result = [
// headers
Object.keys(data['0']),
// values
...Object.values(data).map(item => Object.values(item))
]
.reduce((string, item) => {
string += item.join(',') + '\n';
return string;
}, '');
console.log(result);
Be careful about writing your own code for CSV, there are a lot of edge cases and much more than just combine items with a comma and a newline (what if your data contains commas? how to insert the BOM to make sure your text with a non-ASCII input displays correctly in any spreadsheet software?).
Here's some working example code:
const ObjectsToCsv = require('objects-to-csv');
// Sample data - two columns, three rows:
const data = [
{code: 'HK', name: 'Hong Kong'},
{code: 'KLN', name: 'Kowloon'},
{code: 'NT', name: 'New Territories'},
];
// If you use "await", code must be inside an asynchronous function:
(async () => {
const csv = new ObjectsToCsv(data);
// Save to file:
await csv.toDisk('./test.csv');
// Return the CSV file as string:
console.log(await csv.toString());
})();