validating location submitted by user - javascript

I'm building a web app that calls the mapquest Geocoding API to grab the users lat-long position, and then make a second call to another API to return another set of data. The main issue I am having is when I call the mapquest Geocode API the user can enter any string of characters or made up locations and it returns JSON with data. I need to find a way to prevent this by ensuring the user enters an actual location. Here is the mapquest Geocode API https://developer.mapquest.com/documentation/geocoding-api/address/get/
and I believe my answer lies in here but I am not sure how I would use these to validate the location https://developer.mapquest.com/documentation/geocoding-api/quality-codes/
I've tried setting up a few if statements looking for an X in any of the values for responseJson.results[0].locations[0].geocodeQualityCode
but that still kicked back valid results
this is an example of an acceptable entry that the API returns
{
"info": {
"statuscode": 0,
"copyright": {
"text": "© 2019 MapQuest, Inc.",
"imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
"imageAltText": "© 2019 MapQuest, Inc."
},
"messages": []
},
"options": {
"maxResults": -1,
"thumbMaps": true,
"ignoreLatLngInput": false
},
"results": [
{
"providedLocation": {
"location": "Lawton, ok"
},
"locations": [
{
"street": "",
"adminArea6": "",
"adminArea6Type": "Neighborhood",
"adminArea5": "Lawton",
"adminArea5Type": "City",
"adminArea4": "Comanche County",
"adminArea4Type": "County",
"adminArea3": "OK",
"adminArea3Type": "State",
"adminArea1": "US",
"adminArea1Type": "Country",
"postalCode": "",
"geocodeQualityCode": "A5XAX",
"geocodeQuality": "CITY",
"dragPoint": false,
"sideOfStreet": "N",
"linkId": "282026294",
"unknownInput": "",
"type": "s",
"latLng": {
"lat": 34.606378,
"lng": -98.396817
},
"displayLatLng": {
"lat": 34.606378,
"lng": -98.396817
},
"mapUrl": "http://www.mapquestapi.com/staticmap/v5/map?key=zkn6RGyTDlLGsN8i8RfEmURf2GozTAkL&type=map&size=225,160&locations=34.606378,-98.396817|marker-sm-50318A-1&scalebar=true&zoom=12&rand=197404762"
}
]
}
]
}

Given the Lawton, ok input, the geocoder returns an A5XAX which means that it found a city (A5) with no address match (the first X) an exact city/state match (A) and not postal code match (the second X).
You can plug the returned quality code into the documentation page for a full explanation with some more detail.
The geocode api is not intended to prevent users from entering any string of characters or made up locations by ensuring the user enters an actual location. If the input isn't random keystrokes, there is probably a city or street name that will be a close match and return something other than an X. So the application will need to decide what position it will accept a no-match in and how many no-matches it will accept. For instance, if you need an exact address match for a delivery, you'll want no X and probably all A or B confidences. If a city is ok, then XAX may be fine. As always, it depends.

Related

Get Custom label of people participating with my page through messenger

I am building a dashboard so I can easily view how many people currently have a specific label in my facebook messenger. I'm just developing this for my page that I'm admin at, so it's only for this one page.
The final result is this:
Label 1 - 38 People
Label 2 - 82 People
Label 3 - 47 People
First I get the participants using this endpoints: {page-id}/conversations?fields=participants
I get this sample:
{
"data": [
{
"participants": {
"data": [
{
"name": "Particiapnt's name",
"id": "<psid>"
},
{
"name": "My Page Name",
"id": "<my-pageid>"
}
]
},
"id": "<thread-id>"
}
]
}
Now when I use participants id (psid) to get custom labels using this endpint: /custom_labels
I get this error:
{
"error": {
"message": "Unsupported get request. Object with ID 'xxxxx' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api",
"type": "GraphMethodException",
"code": 100,
"error_subcode": 33,
"fbtrace_id": "A5kFh5U-xSMB83ZnQrbzEfy"
}
}
Please help.

Parsing input based on JSON schema

We're building a frontend project for a web app that communicates with a backend written by another team. Some of the developers work on both projects, and have better understanding of changes to the backend and response fields coming back.
Recently we had portions of frontend break as they made changes in parts of the app based on changes to the backend without updating the logic in all places. To mitigate this I want to put in place a concept of a mask/template that all response data would be curated through. That way the rest of the members on the team who're not as familiar with the backend can notice/address these bugs.
To do so, I'm considering using JSON Schema. Instead of simply validating, however, I want to parse the backend data through it (removing the fields not present in the schema). This way the developer making changes in the frontend in response to a backend change would also need to update this template, therefore triggering a test failure until all logic using this schema is updated (not just the logic he touched). I'm playing with https://www.npmjs.com/package/jsonschema, but it doesn't seem to have a way to remove excess fields, just test for them.
Within JSON Schema, I can also set additionalProperties flag. However, it has 2 problems with it:
It doesn't cause the validator to remove the fields, it simply dumps them to error array
It needs to be set individually at each nested level, therefore I need to traverse the entire JSON structure, at which point I basically end up writing my own parser/validator.
Perhaps validator is not the right tool for this, but that's all I'm finding when searching for JSON schema parsers. Can someone guide me in the right direction so that I don't reinvent the wheel? It sounds like this functionality is very similar to what a validator already does and I would rather do this processing in the same pass.
Found a validator that does what I want: https://github.com/acornejo/jjv. It has removalAdditional flag that I can set, here is a quick test I did:
var jjv = require('jjv')();
var addressSchema = {
"id": "address",
"type": "object",
"properties": {
"lines": {
"type": "array",
"items": {"type": "string"}
},
"zip": {"type": "string"},
"city": {"type": "string"},
"country": {"type": "string"}
},
"required": ["country"]
};
var schema = {
"id": "person",
"type": "object",
"properties": {
"name": {"type": "string"},
"address": {"$ref": "address"},
"votes": {"type": "integer", "minimum": 1}
}
};
var p = {
"name": "Barack Obama",
"address": {
"lines": [ "1600 Pennsylvania Avenue Northwest" ],
"zip": "DC 20500",
"city": "Washington",
"foobar": "baz",
"country": "USA"
},
"a": {
"b": 1,
"c": 2
},
"votes": "lots",
"stuff": "yes"
};
jjv.addSchema('address', addressSchema);
jjv.addSchema('schema', schema);
jjv.defaultOptions.checkRequired = true;
jjv.defaultOptions.removeAdditional = true;
console.log(jjv.validate('schema', p));
console.log(p);
And a response:
{ validation: { votes: { type: 'integer' } } }
{ name: 'Barack Obama',
address:
{ lines: [ '1600 Pennsylvania Avenue Northwest' ],
zip: 'DC 20500',
city: 'Washington',
country: 'USA' },
votes: 'lots' }

Indexing array values in an object in an IndexedDB

For a Chrome app, wich stores data in IndexedDB, i have a object like this:
var simplifiedOrderObject = {
"ordernumber": "123-12345-234",
"name": "Mr. Sample",
"address": "Foostreet 12, 12345 Bar York",
"orderitems": [
{
"item": "brush",
"price": "2.00"
},
{
"item": "phone",
"price": "30.90"
}
],
"parcels": [
{
"service": "DHL",
"track": "12345"
},
{
"service": "UPS",
"track": "3254231514"
}
]
}
If i store the hole object in an objectStore, can i use an index for "track", which can be contained multiple times in each order object?
Or is it needed or possibly better/faster to split each object into multiple objectStores like know from relational DBs:
order
orderitem
parcel
The solution should also work in a fast way with 100.000 or more objects stored.
Answering my own question: I have made some tests now. It looks like it is not possible to do this with that object in only 1 objectStore.
An other example object which would work:
var myObject = {
"ordernumber": "123-12345-234",
"name": "Mr. Sample",
"shipping": {"method": "letter",
"company": "Deutsche Post AG" }
}
Creating an index will be done by:
objectStore.createIndex(objectIndexName, objectKeypath, optionalObjectParameters);
With setting objectKeypath it is possible to address a value in the main object like "name":
objectStore.createIndex("name", "name", {unique: false});
It would also be possible to address a value form a subobject of an object like "shipping.method":
objectStore.createIndex("shipping", "shipping.method", {unique: false});
BUT it is not possible to address values like the ones of "track", which are contained in objects, stored in an array. Even something like "parcels[0].track" to get the first value as index does not work.
Anyhow, it would be possible to index all simple elements of an array (but not objects).
So the following more simple structure would allow to create an index entry for each parcelnumber in the array "trackingNumbers":
var simplifiedOrderObject = {
"ordernumber": "123-12345-234",
"name": "Mr. Sample",
"address": "Foostreet 12, 12345 Bar York",
"orderitems": [
{
"item": "brush",
"price": "2.00"
},
{
"item": "phone",
"price": "30.90"
}
],
"trackingNumbers": ["12345", "3254231514"]
}
when creating the index with multiEntry set to true:
objectStore.createIndex("tracking", "trackingNumbers", {unique: false, multiEntry: true});
Anyhow, the missing of the possibility to index object values in arrays, makes using indexedDB really unneeded complicated. It's a failure in design. This forces the developer to do things like in relational DBs, while lacking all the possibilities of SQL. Really bad :(

Define JSON-LD #context to join/split values?

I'd like to use the expand and compact methods of the jsonld.js library to translate data from various sources into a common format for processing. If I take a source JSON document, add a #context to it, then pass it through the expand method I'm able to get the common format that I need.
The use case that I haven't been able to find a solution for is when multiple values need to be merged. For example, schema.org defines a PostalAddress with a single field for the streetAddress, but many systems store the street address as separate values (street number, street name, street direction...). To translate the incoming data to the schema.org format I need a way to indicate in my #context that multiple fields make up the streetAddress, in the correct order.
Compacted Document
{
"#context": {
"displaName": "http://schema.org/name",
"website": "http://schema.org/homepage",
"icon": "http://schema.org/image",
"streetNumber": "http://schema.org/streetAddress"
},
"displaName": "John Doe",
"website": "http://example.com/",
"icon": "http://example.com/images/test.png",
"streetNumber": "123",
"streetName": "Main St",
"streetDirection": "South"
}
Expanded Document
{
"http://schema.org/name":[
{
"#value":"John Doe"
}
],
"http://schema.org/image":[
{
"#value":"http://example.com/images/test.png"
}
],
"http://schema.org/streetAddress":[
{
"#value":"123"
}
],
"http://schema.org/homepage":[
{
"#value":"http://example.com/"
}
]
}
I've reviewed all of the JSON-LD specs that I could find and haven't been able to locate anything that indicates a way to split or concatenate values using the #context.
Is anyone aware of a way to map multiple values into one context property, in the correct order, and possibly add whitespace between the values. I also need to find a solution for the reverse scenario, where I need to split one field into multiple values, in the correct order.
Note: Even if I map all three properties to streetAddress, the values will all be included in the array, but there's no guarantee they'll be in the correct order.
One possible way to achieve this is to use a single array field for your address containing the ordered address components (i.e. ["number", "direction", "name"]). Then in the #context you can specify the address with #container: #list, which will ensure the address components are correctly ordered.
So the compacted document would be:
{
"#context": {
"displaName": "http://schema.org/name",
"website": "http://schema.org/homepage",
"icon": "http://schema.org/image",
"address": {
"#id": "http://schema.org/streetAddress",
"#container": "#list"
}
},
"displaName": "John Doe",
"website": "http://example.com/",
"icon": "http://example.com/images/test.png",
"address": ["123", "South", "Main St"]
}
And the expanded one would be
{
"http://schema.org/streetAddress": [
{
"#list": [
{
"#value": "123"
},
{
"#value": "South"
},
{
"#value": "Main St"
}
]
}
],
"http://schema.org/name": [
{
"#value": "John Doe"
}
],
"http://schema.org/image": [
{
"#value": "http://example.com/images/test.png"
}
],
"http://schema.org/homepage": [
{
"#value": "http://example.com/"
}
]
}
I posted an issue on the jsonld.js Github repository. According to #dlongley, the original creator of the jsonld.js library, it's not possible to manipulate properties in this manor, using standard JSON-LD.
https://github.com/digitalbazaar/jsonld.js/issues/115

How do I access values in a d3 json file with nested array objects

Previously I was using a json file with the following format:
[{"lat":43.788458853157117,"lng":-79.282781549043008,"category":"volunteer","name":"Rita","url":"", "description":"xxx is a member of 13"},{"lat":43.7,"lng":-79.4,"category":"organization","name":"TCAN","url":"http://tcan.ca","description":"Lorem ipsum"}]
Now I am attempting to generate the json file from a Drupal site and am getting the following structure. How can I reference the lowest level fields. I have looked at examples using d3.net but have not found any that apply.
{
"organizations": [
{
"member": {
"field_category": "organization",
"body": "A network of organizations in Toronto devoted to climate change mitigation and adaptation.",
"URL": "xxx.ca",
"title": "Toronto Climate Action Network",
"field_lat": 43.7,
"field_long": -79.4
}
},
{
"member": {
"field_category": "abc",
"body": "xxx.",
"URL": "",
"title": "yyy",
"field_lat": 43.7,
"field_long": -79.28
}
}
]
}
Assuming that your data is stored in the variable data:
var bottom = data.organizations.map(function(d) { return d.member; });

Categories

Resources