Open 54Factory opened 7 years ago
My question is how would I implement the comparison function into your code?
You can pretty much run the same code, it's normal JS π
I've tried but get the following.... And can't find in the logs?? Sorry to pester and the need for hand holding! But, once I get it....I will assist others and post all snippets!
"code": 5000, "message": "A function returned an unhandled error. Please check the logs for executionId 'cj49xg0wd1dyp0184zup9z7ct'", "requestId": "cj49xg0wd1dyp0184zup9z7ct"
Here is the most current non-working I have....
require('isomorphic-fetch')
module.exports = function (event) {
const baseUrl = 'https://maps.googleapis.com/maps/api/geocode/json'
const apiKey = 'API KEY'
// Here we're merging contents of three inputs β country, city and street.
// You could also have this be just one freestyle address input
// this RegEx replaces spaces with plus signs to fulfill the requirements of the Google geocode API
const addressInput = [event.data.street, event.data.zip].join('+').replace(/\s/g, '+')
const address = encodeURI(addressInput)
// Let's create the url to call
const apiUrl = `${baseUrl}?address=${address}&result_type=street_address&key${apiKey}`
return fetch(apiUrl)
.then((res) => res.json())
.then((json) => {
const location = json.results[0].geometry.location
const addressComponents = json.results[0].address_components;
let i,
j,
types;
let address_component = {}
// Loop through the Geocoder result set. Note that the results
// array will change as this loop can self iterate.
for (i = 0; i < address_components.length; i++) {
address_component = address_components[i];
types = address_component.types;
for (j = 0; j < types.length; j++) {
if (types[j] === 'street_number') {
streetNumber = address_component.long_name;
}
if (types[j] === 'route') {
street = address_component.long_name;
}
if (types[j] === 'neighborhood') {
neighborhood = address_component.long_name;
}
if (types[j] === 'locality') {
city = address_component.long_name;
}
if (types[j] === 'administrative_area_level_1') {
state = address_component.long_name;
}
if (types[j] === 'administrative_area_level_2') {
county = address_component.long_name;
}
if (types[j] === 'postal_code') {
zip = address_component.long_name;
}
if (types[j] === 'postal_code_suffix') {
zip = address_component.long_name;
}
break;
}
// console.log(address_component);
}
const geoLocation = {
// The Lat/Lng values are defined from response "formatted address object" - uncomment live
lat: location.lat,
lng: location.lng,
street: `${streetNumber} ${street}`,
city,
neighborhood,
county,
state,
zip
}
//console.log(geoLocation);
}
// Let's merge the existing location data with Google response
const eventData = Object.assign(event.data, geoLocation);
return {data: eventData}
})
.catch(err => {
console.log(err)
})
}
Could you additional post the mutation that you do to execute the function? Sorry for the delay, somehow I just saw your message right now π
I am not returning the last .then is what I believe. The if statements can be changed to switch. I am having a hard time with the logs so my debugging is non-existent... Please keep I'm mind I am self-taught and have been at this only a few months! I apologize in advance for not really knowing what is going on but I am truly committed to making this work and sharing my solutions with the community.
const addMutation = gql
mutation AddCustomerAndLocation($zip: String!, $state: String!, $city: String!, $street: String!, $locationName: String!, $customer: LocationcustomerCustomer){
createLocation(zip: $zip, state: $state, city: $city, street: $street, locationName: $locationName, customer: $customer){
id
locationName
street
city
state
zip
customer{
id
firstname
lastname
email
phone
}
}
}
;
the whole project is here https://github.com/54Factory/54project
That's right, the missing logs is a problem we're looking into already, I'm sorry it's negatively affecting you. Thanks so much for helping out though!
Could you try this function instead? There indeed was a problem that you did not return in the last then
statement:
require('isomorphic-fetch')
module.exports = function (event) {
const baseUrl = 'https://maps.googleapis.com/maps/api/geocode/json'
const apiKey = 'API KEY'
// Here we're merging contents of three inputs β country, city and street.
// You could also have this be just one freestyle address input
// this RegEx replaces spaces with plus signs to fulfill the requirements of the Google geocode API
const addressInput = [event.data.street, event.data.zip].join('+').replace(/\s/g, '+')
const address = encodeURI(addressInput)
// Let's create the url to call
const apiUrl = `${baseUrl}?address=${address}&result_type=street_address&key${apiKey}`
return fetch(apiUrl)
.then((res) => res.json())
.then((json) => {
const location = json.results[0].geometry.location
const addressComponents = json.results[0].address_components;
let i,
j,
types;
let address_component = {}
// Loop through the Geocoder result set. Note that the results
// array will change as this loop can self iterate.
for (i = 0; i < address_components.length; i++) {
address_component = address_components[i];
types = address_component.types;
for (j = 0; j < types.length; j++) {
if (types[j] === 'street_number') {
streetNumber = address_component.long_name;
}
if (types[j] === 'route') {
street = address_component.long_name;
}
if (types[j] === 'neighborhood') {
neighborhood = address_component.long_name;
}
if (types[j] === 'locality') {
city = address_component.long_name;
}
if (types[j] === 'administrative_area_level_1') {
state = address_component.long_name;
}
if (types[j] === 'administrative_area_level_2') {
county = address_component.long_name;
}
if (types[j] === 'postal_code') {
zip = address_component.long_name;
}
if (types[j] === 'postal_code_suffix') {
zip = address_component.long_name;
}
break;
}
}
const geoLocation = {
// The Lat/Lng values are defined from response "formatted address object" - uncomment live
lat: location.lat,
lng: location.lng,
street: `${streetNumber} ${street}`,
city,
neighborhood,
county,
state,
zip
}
return geoLocation
}).then((geoLocation) =>
// Let's merge the existing location data with Google response
const eventData = Object.assign(event.data, geoLocation);
return {data: eventData}
})
.catch(err => {
console.log(err)
})
}
Also, for me being able to try for myself, I would need the variable values for the mutation you posted above as well π
As a little meta information, formatting your code when posting it on GitHub is very helpful! You can use this syntax:
Ah, and another idea that increases the "feedback loop" for testing this function - use the Playground to trigger it, instead of your app π
Thanks for all the tips! I need them! So that fails and this is the response...
Error
CODE
400
MESSAGE
Compilation failed: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
ERROR
Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at Object.exports.runInThisContext (vm.js:53:16)
at WebtaskModule.compileWebtask (/data/sandbox/lib/module.js:91:32)
at Object.defaultJavascriptCompiler [as nodejsCompiler] (/data/sandbox/lib/compiler.js:124:30)
at module.exports.options.nodejsCompiler.fnCallback (/data/io/2bebdcda0af5491f85eb6ef218389da3/webtask.js:5:11)
at /data/sandbox/lib/compiler.js:230:17
at /data/sandbox/node_modules/async/dist/async.js:3830:24
at replenish (/data/sandbox/node_modules/async/dist/async.js:946:17)
at iterateeCallback (/data/sandbox/node_modules/async/dist/async.js:931:17)
at /data/sandbox/node_modules/async/dist/async.js:906:16
at /data/sandbox/node_modules/async/dist/async.js:3835:13
mutation testGoogleGeocoding {
createLocation(
street: "7 Foster Ave",
city: "Havertown",
state: "Pennsylvania",
zip: "19083"
) {
id
street
neighborhood
city
state
zip
lat
lng
}
}
Also, in my Location Schema I would like to save the lat and lng in the same format as the geocode response. Such as this....geoLocation instead of lat and lng
geoLocation: {
lat: 39.9444071,
lng: -75.1631718
}
All variables inside the loop are undefined (streetnumber, street, etc.), or am I missing something?
I ran into this problem before, and I use this:
let geoResult = {}
addressComponents.forEach(e => e.types.forEach(t => Object.assign(geoResult, {[t]: e.long_name})))
})
That will create an object like this:
{ street_number: '1600',
route: 'Amphitheatre Pkwy',
locality: 'Mountain View',
political: 'United States',
administrative_area_level_2: 'Santa Clara County',
administrative_area_level_1: 'California',
country: 'United States',
postal_code: '94043' }
That's a lot easier to work with!
Also, in my Location Schema I would like to save the lat and lng in the same format as the geocode response. Such as this....geoLocation instead of lat and lng
Create a JSON field geoLocation
on the Location Type. Remove create permissions from that field if you only want to make it available as a result field, not input field. Then set it event.data.geoLocation = { long: ..., lat: ... }
Hi, great work on the geocode function. More of a question than issue.... I am a newb to coding and Graph.cool so hopefully you could help out. When running that function the data in the array result may change positions... For instance an address that has a "neighborhood" type will shift the "locality" to [3], where as an address without a "neighborhood" type "locality" lives in the [2] position. Using static data I reworked some things from other questions on SO....to return values by type. My question is how would I implement the comparison function into your code? Thanks in advance for any help on this!