I have been messing around with googles APIs a little bit, and I am trying to create a in terminal command that tells me how far away I am from something and how long it would take to get there.
The issue that I am having is that when I run:
var axios = require('axios');
var config = {
method: 'get',
url: 'https://maps.googleapis.com/maps/api/distancematrix/json?origins=Washington%2C%20DC&destinations=New%20York%20City%2C%20NY&units=imperial&key=AIzaSyCbwuhNvOJQrYWnLRF6WjzJeOcnhYYfpZA',
headers: {}
};
axios(config)
.then(function(response) {
console.log(JSON.stringify(response.data.rows));
})
.catch(function(error) {
console.log(error);
});
Right now it is outputting:
[{"elements":[{"distance":{"text":"225 mi","value":361918},"duration":{"text":"3 hours 52 mins","value":13938},"status":"OK"}]}]
And I would LIKE the output format to display it like:
you are 225 miles or 3 hours 52 mins away
How would I go about making the output look like the second supplied example?
You can try this, but I'm assuming you are receiving data in this order
I would suggest you to add null checks as well.
let data = [{
"elements": [{
"distance": {
"text": "225 mi",
"value": 361918
},
"duration": {
"text": "3 hours 52 mins",
"value": 13938
},
"status": "OK"
}]
}];
let firstElement = data[0].elements[0];
let constructedString = `You are ${firstElement.distance.text} or ${firstElement.duration.text} away`;
console.log(constructedString);
response.data.rows is a JSON object. JSON.stringify() converts that into a string, which you don't want - you want the object.
If you don't stringify it, you can access the distance string with response.data.rows[0].elements[0].distance.text, and the time with response.data.rows[0].elements[0].duration.text
You could use the following one-liner:
var data = [{"elements":[{ "distance": {"text": "225 mi", "value": 361918}, "duration": {"text": "3 hours 52 mins", "value": 13938}, "status": "OK"}]}];
console.log(`you are ${ data[0].elements[0].distance.text} or ${data[0].elements[0].duration.text} away`);
Related
I am completely new to the topic of APIs and Postman and have the following question:
How can I detect multiple dates in a string and reformat them into a timestamp?
I pulled a JSON format via an API, then converted it to a string via the JSON.stringify function, and then stored it in an environment variable.
It now looks something like this:
[{“date”:“2000-01-01”,“value”:11.8432},{“date”:“2001-01-01”,“value”:112.2348},{“date”:“2002-01-01”,“value”:182.3777},{“date”:“2003-01-01”,“value”:15.0186},{“date”:“2004-01-01”,“value”:131.3781},{“date”:“2005-01-01”,“value”:145.3683}]
Now I’m trying to get this string back into a JSON format but I’d like to add a UNIX time stamp to the date (in milliseconds since January 1, 1970).
So it should look something like this:
[{“date”:946684800000,“value”:11.8432},{“date”:978307200000,“value”:112.2348},{“date”:1009843200000,“value”:182.3777}…
Does anyone know how to solve this within Postman (JavaScript for Postman)?
use moment library and the valueOf() method:
moment = require('moment')
let date = [{ "date": "2000-01-01", "value": 11.8432 }, { "date": "2001-01-01", "value": 112.2348 }, { "date": "2002-01-01", "value": 182.3777 }, { "date": "2003-01-01", "value": 15.0186 }, { "date": "2004-01-01", "value": 131.3781 }, { "date": "2005-01-01", "value": 145.3683 }]
date = date.map((item) => {
item.date = moment(item.date, "YYYY-MM-DD").valueOf()
return item
});
console.log(date)
I am trying to read JSON response data from a Restful API that contains a space in the path. I am trying to accomplish this in JavaScript, but can't seem to get the data to display.
Below is the JSON I am working with:
"fields": {
"census": {...},
"acs": {
"meta": {
"source": "American Community Survey from the US Census Bureau",
"survey_years": "2014-2018",
"survey_duration_years": "5"
},
"demographics": {
"Median age": {
"meta": {
"table_id": "B01002",
"universe": "Total population"
},
"Total": {
"value": 32.8,
"margin_of_error": 0.6
As you can see, the Median Age field has a space. The actual data I am trying to obtain is the Median age total value.
Below is my JSON path that isn't working:
let ageDems = await response.data.results[0].fields.demographics.$["Median age"].Total.value;
I have also tried to use ['Median Age'], ["Median Age"] and Median+Age and none of those worked either.
Can anyone please assist me in writing the correct path to obtain the data I need?
await response.data.results[0].fields.demographics["Median age"].Total.value;
Ismail's suggestion does work.
This answer is here just to prove it to you. If this is not working for you as demonstrated below, please provide a Minimal, Reproducible Example that shows the error you see.
const data = {
"acs": {
"meta": {
"source": "American Community Survey from the US Census Bureau",
"survey_years": "2014-2018",
"survey_duration_years": "5"
},
"demographics": {
"Median age": {
"meta": {
"table_id": "B01002",
"universe": "Total population"
},
"Total": {
"value": 32.8,
"margin_of_error": 0.6
}
}
}
}
};
console.log(data.acs.demographics["Median age"].Total.value);
demographics is nested under acs:
await response.data.results[0].fields.acs.demographics["Median age"].Total.value
When I try to parse this JSON (Discord webhook):
{
"content": "this `supports` __a__ **subset** *of* ~~markdown~~ 😃 ```js\nfunction foo(bar) {\n console.log(bar);\n}\n\nfoo(1);```",
"embed": {
"title": "title ~~(did you know you can have markdown here too?)~~",
"description": "this supports [named links](https://discordapp.com) on top of the previously shown subset of markdown. ```\nyes, even code blocks```",
"url": "https://discordapp.com",
"color": 16324973,
"timestamp": "2018-12-18T09:22:12.841Z",
"footer": {
"icon_url": "https://cdn.discordapp.com/embed/avatars/0.png",
"text": "footer text"
},
"thumbnail": {
"url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"image": {
"url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"author": {
"name": "author name",
"url": "https://discordapp.com",
"icon_url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"fields": [
{
"name": "🤔",
"value": "some of these properties have certain limits..."
},
{
"name": "😱",
"value": "try exceeding some of them!"
},
{
"name": "🙄",
"value": "an informative error should show up, and this view will remain as-is until all issues are fixed"
},
{
"name": "<:thonkang:219069250692841473>",
"value": "these last two",
"inline": true
},
{
"name": "<:thonkang:219069250692841473>",
"value": "are inline fields",
"inline": true
}
]
}
}
Using this code:
var parsed = JSON.parse(req.body)
I get this error:
SyntaxError: Unexpected token o in JSON at position 1
But if I use a website such as
https://jsonformatter.curiousconcept.com
To validate the JSON, it says the JSON is valid.
What is wrong here?
UPDATE
I'm using an express server to simulate discord server, so it sends web hooks to the express server instead, I get the JSON using req.body.
This happens because JSON is a global object (it's the same object where you read the method parse!), so when you invoke JSON.parse(JSON) javascript thinks you want to parse it.
The same thing doesn't happen when you pass the variable to the validator, because it will be assigned to a local variable:
let JSON = "{}";
validate(JSON);
function(x) {
JSON.parse(x); // here JSON is again your global object!
}
EDIT
According to your updated question, maybe it happens because you already use bodyParser.json() as middleware, and when you use it, req.body is already an object and you don't need to parse it again.
Trying to parsing an already parsed object will throw an error.
It would be something like without using JSONStream:
http.request(options, function(res) {
var buffers = []
res
.on('data', function(chunk) {
buffers.push(chunk)
})
.on('end', function() {
JSON.parse(Buffer.concat(buffers).toString())
})
})
For using it with JSONStream, it would be something like:
http.request(options, function(res) {
var stream = JSONStream.parse('*')
res.pipe(stream)
stream.on('data', console.log.bind(console, 'an item'))
})
(OR)
Here is the Some Steps for this issue..
You Can use lodash for resolving this.
import the lodash and call unescape().
const _ = require('lodash');
let htmlDecoder = function(encodedStr){
return _.unescape(encodedStr);
}
htmlDecoder(JSON);
I am using the wonderful json-server as the backend of my application and it's really useful for hitting custom endpoints to retrieve some data. but what would be super useful if it allowed me to do calculations/expression so that i can mimic that backend behaviour too.
take this data structure for example
{
"products": [
{
"name": "football",
"id": "SPO-001",
"category": "sport",
"price": 40,
"couponApplied": "false",
"coupons": [
"daw124qdw",
"a1212cxn"
]
}
]
}
I would like some way of saying something like "discountPrice": couponApplied ? price * couponDiscount
that's just me pseudo coding. but I would like to do something where I can calculate the price on the fly. or when I make a request it does a calculation and returns me the calculated data (like a backend app would)
I understand I can make a request, apply the coupon and render that new price. or even make a post request and change the price. but that is all done client side. is there any way to do this either with json or json-server or any other solutions. if that makes sense?
JSON means JavaScript Object Notation and is data structure, and does not have any preprocessor for it. You can use any JSON parser and append/change values that you need dynamically.
So in short: no, there is no possibility to add dynamic values
No, you'll not be able to do computations inside json. The data would need to be mutated elsewhere and then sent.
No, it isn't possible to do math or any kind of expression in JSON as JSON is just a data structure format, and not a programming language.
You will need to load the JSON data in using a programming language of your choice, at which point you can then manipulate it.
For example, since you mention javascript a simple Node program as an example..
//It would be better to use the FileSystem API, but for simplicity for this example, I'm using require
var json = require('./myjson.json');
var product = json.products[0];
//Since the dataset has "false", this if will handle both "false" (string) and false (boolean) values. The value should really be boolean if possible
product.discountPrice = product.couponApplied && product.couponApplied !== "false" ? product.price * couponDiscount : null;
If you are trying to create logic dynamically, like user creates some logic, and you want to save it into DB and later apply it somewhere, these might be useful:
An Excel like formula parser + a bit of JS codes to put data into formulas.
JSONLogic
MongoDB aggregation pipeline operations are being used in an Array of Object. Same behavior can be used inside JSON object, but you need an implementation to take care of it, something like Mingo. Check arithmetic sum for example. This JS implementation might help.
In your example, using formula parser could be like:
const response = {
"products": [
{
"name": "football",
"id": "SPO-001",
"category": "sport",
"price": 40,
"couponApplied": "false",
"coupons": [
"daw124qdw",
"a1212cxn"
]
},
{
"name": "football",
"id": "SPO-001",
"category": "sport",
"price": 40,
"couponApplied": "true",
"couponDiscount": 0.2,
"coupons": [
"daw124qdw",
"a1212cxn"
]
}
],
formulaFields: {
"discountPrice": 'IF("{couponApplied}"="true", {price} * {couponDiscount}, "")', // excel standard formula, with {variable} as product field keys
}
}
const productsWithValues = response.products.map((product)=>{
const productWithValues = { ...product };
for (const field in response.formulaFields){
const formula = response.formulaFields[field].replace(/\{([^\}]+)\}/g, (_, key) => product[key])
const parser = new Parser();
const { result } = parser.parse(formula);
productWithValues[field] = result;
}
return productWithValues;
})
console.log(productsWithValues)
Output:
[
{
"name": "football",
"id": "SPO-001",
"category": "sport",
"price": 40,
"couponApplied": "false",
"coupons": ["daw124qdw", "a1212cxn"],
"discountPrice": null
},
{
"name": "football",
"id": "SPO-001",
"category": "sport",
"price": 40,
"couponApplied": "true",
"couponDiscount": 0.2,
"coupons": ["daw124qdw", "a1212cxn"],
"discountPrice": 8
}
]
JSON doesn't support this, but if you turn it into a Javascript object, you could do something like this:
var obj = JSON.parse(
`{
"products": [
{
"name": "football",
"id": "SPO-001",
"category": "sport",
"price": 40,
"couponApplied": "true",
"couponDiscount": 0.5,
"coupons": [
"daw124qdw",
"a1212cxn"
]
}
]
}`).products[0];
Object.defineProperty(obj,"discountPrice",{
get:function(){
return (this.couponApplied==="true"||this.couponApplied===true) ? this.price*this.couponDiscount : this.price;
},
set:function(){
return;
}
});
console.log(obj.discountPrice);
This uses an accessor descriptor to define an object property that depends on the values of the other object properties.
Note that json-server allow you to add custom middleware. So you could write something like this:
const updateProduct = (p) => ({
...p,
discountPrice: p.couponApplied ? p.price * p.couponDiscount : p.price
})
const transform = ({products, ...rest}) => ({
...rest,
products: products.map(updateProduct)
})
const modify = (req, res, next) => {
if (req.path !== '/my-route') return next();
res.body = JSON.stringify(transform(JSON.parse(res.body)))
next();
}
// dummy call -- would really be handled by json-server/express
(() => {
const req = {path: '/my-route'};
const res = {body: `{"products":[{"name":"football","id":"SPO-001","category":"sport","price":40,"couponApplied":false,"coupons":["daw124qdw","a1212cxn"]},{"name":"helmet","id":"SPO-042","category":"sport","price":50,"couponApplied":true,"couponDiscount":0.75,"coupons":["foobarbaz"]}]}`}
const next = () => {console.log(JSON.parse(res.body))}
modify(req, res, next)
})()
I wanted to know if there is some performance issue related in the two below coding paradigms. Which one is the best and why?
var data = [{
"name": "ABC",
"code": 1,
"age": 97
},{
"name": "XYZ",
"code": 12,
"age": 12
},{
"name": "LMN",
"code": 121,
"age": 172
}
];
var response = [];
Method1
data.forEach(function(entry){
var obj = {
"NAME": entry["name"],
"AGE": entry["age"]
};
response.push(obj);
});
Method2
data.forEach(function(entry){
var obj = {};
obj["NAME"] = entry["name"];
obj["AGE"] = entry["age"];
response.push(obj);
});
For output object, I need say suppose, only 10 keys out of 100 keys
The object has many keys in it. Only limited are shown in the example. Which coding standard to choose and why? Please, can anybody explain?
No need to create the objects and then make a Array.prototype.push() for everly loop iteration...
You can directly use Array.prototype.map() instead of Array.prototype.forEach() and better access the object property values by the dot notation:
const data = [{
"name": "ABC",
"code": 1,
"age": 97
},{
"name": "XYZ",
"code": 12,
"age": 12
},{
"name": "LMN",
"code": 121,
"age": 172
}
];
const response = data.map(obj => ({
NAME: obj.name,
AGE: obj.age
}));
console.log(response)
Both approaches are fine and one should not be "faster" than the other, at least not enough to justify using the other one. Use the one you like.
But, if you're still looking for closure. The first one should be faster since it defines the entire object all at one go. There's no "look-ups" the engine have to do. It's all done at one go.
On a separate note, consider using the dot notation, it should be faster since the engine will not have to create strings. So, change
entry["name"]
to
entry.name
Also, if this is your actual code and the purpose is to modify the result to have just name and age and no code. You can do
data.forEach(user => delete user.code)