craft3-fields icon indicating copy to clipboard operation
craft3-fields copied to clipboard

Is there a reason the Address field is double-encoding some of the JSON?

Open adrienne opened this issue 3 years ago • 5 comments

@leevigraham : When you save an address field, it saves as JSON, of course. But the placeData key, which is the part that gets pulled in wholesale from Google Places/Maps, is string-encoded inside the JSON, so you get something in the database that looks like this:

{
	"country": {},
	"placeData": "{\r\n    \"address_components\": [\r\n        {\r\n            \"long_name\": \"270\",\r\n            \"short_name\": \"270\",\r\n            \"types\": [\r\n                \"street_number\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"Goffe Street\",\r\n            \"short_name\": \"Goffe St\",\r\n            \"types\": [\r\n                \"route\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"Dixwell\",\r\n            \"short_name\": \"Dixwell\",\r\n            \"types\": [\r\n                \"neighborhood\",\r\n                \"political\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"New Haven\",\r\n            \"short_name\": \"New Haven\",\r\n            \"types\": [\r\n                \"locality\",\r\n                \"political\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"New Haven County\",\r\n            \"short_name\": \"New Haven County\",\r\n            \"types\": [\r\n                \"administrative_area_level_2\",\r\n                \"political\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"Connecticut\",\r\n            \"short_name\": \"CT\",\r\n            \"types\": [\r\n                \"administrative_area_level_1\",\r\n                \"political\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"United States\",\r\n            \"short_name\": \"US\",\r\n            \"types\": [\r\n                \"country\",\r\n                \"political\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"06511\",\r\n            \"short_name\": \"06511\",\r\n            \"types\": [\r\n                \"postal_code\"\r\n            ]\r\n        },\r\n        {\r\n            \"long_name\": \"3302\",\r\n            \"short_name\": \"3302\",\r\n            \"types\": [\r\n                \"postal_code_suffix\"\r\n            ]\r\n        }\r\n    ],\r\n    \"adr_address\": \"<span class=\\\"street-address\\\">270 Goffe St<\/span>, <span class=\\\"locality\\\">New Haven<\/span>, <span class=\\\"region\\\">CT<\/span> <span class=\\\"postal-code\\\">06511-3302<\/span>, <span class=\\\"country-name\\\">USA<\/span>\",\r\n    \"formatted_address\": \"270 Goffe St, New Haven, CT 06511, USA\",\r\n    \"geometry\": {\r\n        \"location\": {\r\n            \"lat\": 41.3185014,\r\n            \"lng\": -72.9386131\r\n        },\r\n        \"viewport\": {\r\n            \"south\": 41.31715241970851,\r\n            \"west\": -72.93996208029151,\r\n            \"north\": 41.31985038029151,\r\n            \"east\": -72.9372641197085\r\n        }\r\n    },\r\n    \"icon\": \"https:\/\/maps.gstatic.com\/mapfiles\/place_api\/icons\/v1\/png_71\/geocode-71.png\",\r\n    \"icon_background_color\": \"#7B9EB0\",\r\n    \"icon_mask_base_uri\": \"https:\/\/maps.gstatic.com\/mapfiles\/place_api\/icons\/v2\/generic_pinlet\",\r\n    \"name\": \"270 Goffe St\",\r\n    \"place_id\": \"EiYyNzAgR29mZmUgU3QsIE5ldyBIYXZlbiwgQ1QgMDY1MTEsIFVTQSJREk8KNAoyCTH9Muyl2eeJEbPCzSoT3VEuGh4LEO7B7qEBGhQKEgmJ6aI2tNnniRGO-lGlZOfpAgwQjgIqFAoSCYfa9Jiv2eeJEZ1fzTjdK3eU\",\r\n    \"reference\": \"EiYyNzAgR29mZmUgU3QsIE5ldyBIYXZlbiwgQ1QgMDY1MTEsIFVTQSJREk8KNAoyCTH9Muyl2eeJEbPCzSoT3VEuGh4LEO7B7qEBGhQKEgmJ6aI2tNnniRGO-lGlZOfpAgwQjgIqFAoSCYfa9Jiv2eeJEZ1fzTjdK3eU\",\r\n    \"types\": [\r\n        \"street_address\"\r\n    ],\r\n    \"url\": \"https:\/\/maps.google.com\/?q=270+Goffe+St,+New+Haven,+CT+06511,+USA&ftid=0x89e7d9a5ec32fd31:0x5dd9f8981b6223a0\",\r\n    \"utc_offset\": -240,\r\n    \"vicinity\": \"New Haven\",\r\n    \"html_attributions\": [],\r\n    \"utc_offset_minutes\": -240\r\n}",
	"latitude": "41.3185014",
	"longitude": "-72.9386131",
	"mapUrl": "https:\/\/maps.google.com\/?q=270+Goffe+St,+New+Haven,+CT+06511,+USA&ftid=0x89e7d9a5ec32fd31:0x5dd9f8981b6223a0",
	"countryCode": "US",
	"administrativeArea": "CT",
	"locality": "New Haven",
	"dependentLocality": null,
	"postalCode": "06511",
	"sortingCode": null,
	"addressLine1": "270 Goffe St",
	"addressLine2": "",
	"organization": null,
	"recipient": null,
	"givenName": null,
	"additionalName": null,
	"familyName": null,
	"locale": null
}

Is there a reason why you're not just storing the returned JSON as subkeys of placeData rather than stringifying (and therefore double-encoding) it?

(I discovered the problem via writing a front-end interface to the field so we can use it on a guest form. Storing it without double-encoding it causes the back-end edit interface to throw an error about array-to-string conversion.)

adrienne avatar Sep 21 '21 16:09 adrienne

Hmm… I'll take a look. An update to NSM Fields is on the schedule for this week.

leevigraham avatar Sep 22 '21 00:09 leevigraham

@leevigraham - you're definitely stringifying it explicitly here: https://github.com/newism/craft3-fields/blob/4cc283c04687578fff98cd9b9516801799e52061/src/assetbundles/AddressField/dist/js/Address.js#L221

The field input is expecting it to be a string: https://github.com/newism/craft3-fields/blob/4cc283c04687578fff98cd9b9516801799e52061/src/templates/_components/fieldtypes/Address/input.twig#L83

But i assume you can de-stringify it on submit and re-stringify it as necessary? It would definitely make more sense to have the whole thing stored as actual JSON (as well as being less of a pain in my personal ass).

adrienne avatar Sep 22 '21 15:09 adrienne

I'm submitting a pull request with the absolute minimum possible fix: it stringifies any unencoded array data for the text field display, and otherwise leaves everything exactly as is. This avoids any weird behavior from front-end forms, while otherwise keeping everything identical, @leevigraham .

adrienne avatar Oct 28 '21 14:10 adrienne

I still think in the long run you should probably just not stringify it in the first place, but this is a minimal fix that doesn't affect any existing field behavior.

adrienne avatar Oct 28 '21 16:10 adrienne

@leevigraham bump (making sure you see this!)

adrienne avatar Dec 03 '21 06:12 adrienne