Getting the street address from a google maps geocode call - parsing

I am geocoding an address using google maps API, and I need to get the street address, city, state, and zip in distinct fields. Based on the documentation of the address component types that are returned in the result, this is my code:
var address = "";
var city = "";
var state = "";
var zip = "";
geocoder.geocode( { 'address': inputAddress}, function(results, status){
if (status==google.maps.GeocoderStatus.OK){
// loop through to get address, city, state, zip
$.each(results[0].address_components, function(){
switch(this.types[0]){
case "postal_code":
zip = this.short_name;
break;
case "street_address":
address = this.short_name;
break;
case "administrative_area_level_1":
state = this.short_name;
break;
case "locality":
city = this.short_name;
break;
}
});
} else{ alert("Invalid Address"); }
});
However, it seems that when I enter addresses, "street_address" is not being returned; instead, it is returned as separate fields, most often "street_number" and "route", occasionally additional fields (such as "subpremise" for apt number). See this example of a geocoding result in the docs.
How can I get an address variable that holds any fields related to the street address? For the example in the docs, I would want "1600 Ampitheatre Parkway".

Based on the docs street_address is an address type, but that does not necessarily mean it's a type of address component - it could just be a tag used for the types array - returned with each of the objects in the results array:
The types[] array within the returned result indicates the address type. These types may also be returned within address_components[] arrays to indicate the type of the particular address component.
What you probably should be doing is traversing through your results array first and find the one that includes a street_address in the types array. Then use that object to get the formatted_address attribute (as mentioned by Aperçu). As the doc states: "the formatted_address is a string containing the human-readable address of this location". When the type is street_address, the formatted_address is equal to a street_number + route (followed by whatever other address_components are available). So you can either split(',') the formatted_address string to get the components you need - or use the address_components array of that particular object in the results array to grab the components that you need (of course doing it this way you'll need to concat the street_number and route yourself - so added logic is needed).

If you want to get all address fields in a string, use the 'formatted_address' property:
Code:
var geocoder = new google.maps.Geocoder();
var fullAdressData = '';
geocoder.geocode( { 'address': inputAddress}, function(results, status){
if (status==google.maps.GeocoderStatus.OK){
fullAdressData = results[0].formatted_address;
} else{ alert("Invalid Address"); }
});

use "route" instead of "street_address"...
case "route":
address = this.short_name;
alert(address);
break;

Related

How to make multiple versions of the same record, with F#

I have 3 state machines that follow the similar model:
- same states
- same calls for each state
only the implementation of these calls change.
All the data is carried in a single record that also contains a DU that has the state and there are also a few other common parameters. Each implementation also adds their own fields to that record.
So I would like to figure out if there is a way to make a record I can extend but that contains a number of common fields that the code is expecting to find. Something similar to an interface for a type, but for a record.
For example:
type State =
| a
| b
type StateMachine1StateObject =
{
State: State
SomeData: ...
}
type StateMachine2StateObject =
{
State: State
SomeOtherKindOfData: ...
}
and I would like to have a single state machine loop (which is really a mailbox processor loop) take all the same messages, and be able to rely on some fields that will always be there in that type, but the records themselves may be different as they contain their own fields.
How can this be structured? It looks like I can't use interfaces with records nor combine multiple records into one.
If you have a lot of data in common then can create for example a record, with a field, that has a generic type.
type State<'a> = {
Name: string
Id: int
Extended: 'a
}
type Person = {
FirstName: string
LastName: string
}
type Computer = {
CPU: string
Ghz: float
}
This way, you can create a state that have different Extended data
// State<Person>
let x = {
Name = "foo"
Id = 1
Extended = {
FirstName = "David"
LastName = "Raab"
}
}
// State<Computer>
let y = {
Name = "bar"
Id = 2
Extended = {
CPU = "AMD"
Ghz = 3.6
}
}
You also could convert from one record to another. Your state machine, only accepts a record with those data it needs. For exmaple, you have a state machine that only needs Name and Id. You create.
type StateA = {
Name: string
Id: int
}
Assume you now have a different state with shared keys.
type StateB = {
Name: string
Id: int
Extra: float
}
Instead of type hackery, generics and so on, the easiest way is just to convert from B to A.
let stateBtoA (record:StateB) : StateA = {
Name = record.Name
Id = record.Id
}
So your state machine only accepts StateA, and you have a bunch of function, and other types must be converted to StateA before passing it to the state machine.
If for some reason your state machine, needs access to the orignal data, you should be able to pass it as a generic paramter to a function call. Like
message (x:StateA) (y:'a) : 'a =
// do something with x
y
message (stateBtoA data) data
So your function could work on the first argument, that is of StateA, and for example returns the second argument y that could be StateB. As long your function does nothing with y. It should be generic.

Write Custom Validation for Multiple Fields using MVC

I have a customer form having phone number fields like CountryCode, AreaCode and PhoneNumber. I would like to write a custom validation for these 3 fields where all of them can either remain empty (they are optional) or all of them can remain filled (no field can be left empty if one or two are filled).
Am trying to write a custom validation for this situation, however, am not clear how to do it. Please help.
It's unclear exactly what you're looking for here. If you're just struggling with the boolean logic, all you need is:
if (!String.IsNullOrWhiteSpace(model.CountryCode) ||
!String.IsNullOrWhiteSpace(model.AreaCode) ||
!String.IsNullOrWhiteSpace(model.PhoneNumber))
{
if (String.IsNullOrWhiteSpace(model.CountryCode)
{
ModelState.AddModelError(nameof(model.CountryCode), "Country code is required.");
}
if (String.IsNullOrWhiteSpace(model.AreaCode)
{
ModelState.AddModelError(nameof(model.AreaCode), "Area code is required.");
}
if (String.IsNullOrWhiteSpace(model.PhoneNumber)
{
ModelState.AddModelError(nameof(model.PhoneNumber), "Phone number is required.");
}
}
Essentially, you just first check to see if any of them have a value. Then, you individually add an error for each one that does not have a value.
That said, these broken out phone number fields are atrocious. I'm not sure where the idea came from, but it's like you just can't get people off of them now. Phone number formats vary wildly, and not every phone number actually has an "area code". It's far better to have a single "phone" field where the user can simply type their entire phone number. Then, you can use something like this port of Google's libphonenumber library to validate the number and format it into a standard form. You can even use the library to parse out the individual pieces of country code, area code, and number, if you need to store it like this. Just be prepared that the area code may not have a value and even if it does, it may not be exactly 3 digits. Same goes for number portion, as well: you can't assume it will always be 7.
Validate a phone number
var phoneUtil = PhoneNumberUtil.GetInstance();
try {
var phoneNumber = phoneUtil.Parse(model.Phone, countryISO2);
if (!phoneUtil.IsValidNumber(phoneNumber))
{
ModelState.AddModelError(nameof(model.Phone), "Invalid phone number.");
}
} catch (NumberParseException) {
ModelState.AddModelError(nameof(model.Phone), "Invalid phone number.");
}
Where countryISO2 is the two character country code: "US", "GB", etc. If you want to accept international phone numbers, you should collect the country from the user.
Format a phone number
phoneUtil.Format(phoneNumber, PhoneNumberFormat.NATIONAL);
Get component parts of a phone number
var countryCode = phoneNumber.CountryCode;
string areaCode;
string number;
var nationalSignificantNumber = phoneUtil.GetNationalSignificantNumber(phoneNumber);
var areaCodeLength = phoneUtil.GetLengthOfGeographicalAreaCode(phoneNumber);
if (areaCodeLength > 0) {
areaCode = nationalSignificantNumber.Substring(0, areaCodeLength);
number = nationalSignificantNumber.Substring(areaCodeLength);
} else {
areaCode = "";
number = nationalSignificantNumber;
}

How does the Dart URI class QueryParameters handle Map values?

According to the documentation, it needs to follows the Form Post rules at: https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4. When looking at that information it did not give me much to work with in terms of complex objects or maps.
Right now, If I have a list for example: Each item in the list needs to be stringified.
var params = {"list": [1,2,3]};
// needs to be stringed.
params["list"] = params["list"].map((item)=>item.toString()).toList();
Simple. Also all base items need to be a string as well
var params = {"number": 1, "boolean": true};
params = params.forEach((k,v)=> params[k].toString());
But how do we handle maps?
var params = {"map": {"a":1,"b":"foo","c":false,"d":[]}};
// ??
It seems that after testing in my app and in dart pad, you need to make sure everything is strings, so i am trying to come up with a way to effectively cover lists, maps, and maybe more complex objects for encoding.
var params = {};
params["list"] = [1,2,3];
params["number"] = 1;
params["boolean"] = true;
params["map"] = {"a":1,"b":"foo","c":false,"d":[]};
params.forEach((String key, dynamic value){
if(value is List){
params[key] = value.map((v)=>v.toString()).toList();
}else if(value is Map){
// ????
}else{
params[key] = value.toString();
}
//maybe have an additional one for custom classes, but if they are being passed around they should already have their own JSON Parsing implementations.
}
Ideally, the result of this would be passed into:
Uri myUri = new Uri(queryParameters: params);
and right now, while i solved the list issue, it doesn't like receiving maps. Part of me just wanted to stringify the map as a whole, but i wasn't not sure if there was a better way. I know that when someone accidentally stringified the array, it was not giving me: ?id=1&id=2 but instead ?id=%5B1%2C2%5D which was not correct.
I don't think there is any special support for maps. Query parameters itself is a map from string to string or string to list-of-strings.
Everything else need to be brought into this format first before you can pass it as query parameter.
A simple approach would be to JSON encode the map and pass the resulting string as a single query parameter.

Comparing strings in an array to another array using switch case

I am new here so please forgive me if I do not ask the right question. I am trying to create a function that will take array of strings ( medications) and then will tell if it belongs to certain categories by comparing it against other arrays. I am trying to achieve this with case switch method. But it is giving me error "can't form range upperBound
The code if have is :
//This is list of medications a patient may be on. This array will be generated by user input.
var medicationArray = ["metoprolol", "Dulera", "Atrovastatin", "Albuterol", "lasix", "Sprinolactone", "Lisnopril","Aspirin","Apixaban"]
//Function to compare medications above to arrays of different categories of medications.
func medDetails(medications : [String]) {
//Arrays of list of different types of mjedications
let betaBlockerList = ["metoprolol", "carvedilol", "propanolol"]
let anticoagulantList = ["warfarin", "Apixaban","rivroxaban"]
var otherMedicationList : String = ""
// For loop to loop thru different medications patient is on.
for medication in medications {
//switch function to take the medication name and then comparing it against different arrays.
switch medication {
//comparing medication against the range of of elements of first array.
case anticoagulantList[0]...anticoagulantList[anticoagulantList.count-1]:
print("Patinet is on \(medication) for anticoagultion")
//comparing medication against the range of of elements of second array.
case betaBlockerList[0]...betaBlockerList[betaBlockerList.count-1]:
print("Patient is on \(medication) for betablocker")
//list of medications that do not fit any of the above two categorias.
default:
otherMedicationList = medication + ", "
if medication == medications[medications.count - 1]{
print("Patients other medications inculde \(otherMedicationList) .")
}
}
}
}
medDetails(medications: medicationArray
let betaBlockerList = ["metoprolol", "carvedilol", "propanolol"]
Your switch case for "betaBlockerList" works fine. It is taking characters from "m" to "p" as parameters. Here these two values are in ascending order.
let anticoagulantList = ["warfarin", "Apixaban","rivroxaban"]
Your switch case for "anticoagulantList" is not working due to non ascending order of "(w)arfarin" and "(r)ivroxaban"
Switch cases here is not taking the whole strings as their parameters. Your betaBlockerList case is executing for all below values too
var medicationArray = ["metoprolol", "n", "o"]
I think a switch is not really a best practice here. A good approach would be to use a search function that searches or filters your array based on a given premise. But if you want to implement a more naive solution, simply do two for loops. One for the medicines and one for the other array that you are comparing against. Then add an if statement inside the loops, checking if the medicine is part of that list, if so, you have found your answer and you can break the loop at that point.
#Nirav already commented on the error, but the thing is that a switch might not be the best solution for your problem (what if you had 300 groups for example?)
So, here is a version that would require only a definition of the groups:
var medicationArray = ["metoprolol", "Dulera", "Atrovastatin", "Albuterol", "lasix", "Sprinolactone", "Lisnopril","Aspirin","Apixaban"]
func medDetails(medications: [String]) {
let input = Set(medications)
let betaBlockerList = Set(["metoprolol", "carvedilol", "propanolol"])
let anticoagulantList = Set(["warfarin", "Apixaban","rivroxaban"])
let groups = [
"betablocker": betaBlockerList,
"anticoagultion": anticoagulantList
]
// Get rid of any element from input that is present in groups
let unmatched = input.subtracting(groups.values.flatMap({$0}))
for medication in input {
for (groupName, groupValues) in groups {
if groupValues.contains(medication) {
print("Patient is on \(medication) for \(groupName)")
break
}
}
}
print("Patients other medications include: \(unmatched.joined(separator: ", "))")
}
Which when called like medDetails(medications: medicationArray) prints
Patient is on metoprolol for betablocker
Patient is on Apixaban for anticoagultion
Patients other medications include: Sprinolactone, Atrovastatin, Dulera, Albuterol, Aspirin, Lisnopril, lasix

How do I access the information in this dictionary? - Swift

I am new to Swift. I am trying to make a simple REST call and access the data that is returned. I am testing with the Zippopotam API, which returns city information based on zipcode. I get the result from the REST call and put it into a dictionary:
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data,
options:NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
Here is some of the data that prints out when I print the json:
{
country = "United States";
"country abbreviation" = US;
places = (
{
latitude = "40.5541";
longitude = "-111.9539";
"place name" = "South Jordan";
state = Utah;
"state abbreviation" = UT;
}
);
"post code" = 84095;
}
First of all, is there a better way to access a key value pair than
json["post code"].text!
That seems so low level to get the information, but maybe that is the only way to do it in Swift.
Next, my places are a tuple. When I access the places, I get the information in parentheses ( info ...). How do I access the state in the first tuple? I have tried json["places"].0["state"], but that is not correct.
JSON only has three basic types - arrays, dictionaries and strings. These are mapped by NSJSONSerialization to NSDictionary (which is bridged to a Swift dictionary), NSArray (bridged to Swift array) and NSString (bridged to String).
The simplest way to access the data returned by NSJSONSerialization is to just read the dictionaries & arrays as you have.
In the case of 'places' it is an array of dictionaries so to get 'state' you can say
if let places=json["places"] as? [[String:AnyObject]] {
if (places.count > 0) {
let place=places[0]
let state=place["state"] as! String
}
}
The "better" way is to take the JSON and use it create objects with appropriate properties. Unfortunately unlike XML which can use a defined schema to automatically generate this 'parsing' code you have to do this yourself

Resources