API Management Conditional Flow Policy - azure-api-management

I have the following request data
{
"id": "1115e297-12de-4189-8e11-75a8354f77d6",
"type": "transaction",
"version": "1.0.0",
"data": {
"account_id": "999",
"customer_info": {
"client_id": 999
},
"company_id": "999999",
"event": {
"id": 99999999,
"type_code": "3098"
}
}
}
I want to write a policy that ignores the request unless the type is "transaction" and the type_code is "3098" or "3099"
If this is not satisfied then it should just return the id of the request to the caller and not forward on the request
Here is what I have come up with
<choose>
<when condition="#((string)context.Request.Body?.As<JObject>(true)["type"] != "transaction")">
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var json = new JObject(
new JProperty("id", context.Request.Body?.As<JObject>(true)["id"])
);
return json.ToString();
}</set-body>
</return-response>
</when>
<when condition="#(context.Request.Body?.As<JObject>(true)["data"] == null || context.Request.Body?.As<JObject>(true)["data"]["event"] == null)">
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var json = new JObject(
new JProperty("id", context.Request.Body?.As<JObject>(true)["id"])
);
return json.ToString();
}</set-body>
</return-response>
</when>
<when condition="#((int)context.Request.Body?.As<JObject>(true)["data"]["event"]["type_code"] != 3098 && (int)context.Request.Body?.As<JObject>(true)["data"]["event"]["type_code"] != 3099)">
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var json = new JObject(
new JProperty("id", context.Request.Body?.As<JObject>(true)["id"])
);
return json.ToString();
}</set-body>
</return-response>
</when>
</choose>
I'm tipping there is a much more elegant way to do this?

Sure. Provided all you return-response policies are the same you can use multiline expression:
<set-variable name="payload" value="#((string)context.Request.Body?.As<JObject>(true))" />
<choose>
<when condition="#{
var payload = (JObject)context.Variables["payload"];
if (payload?["type"] != "transaction"
|| payload?["data"]?["event"]?["type_code"] != 3099)
{
return true;
}
}">
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var payload = (JObject)context.Variables["payload"];
var json = new JObject(
new JProperty("id", payload?["id"])
);
return json.ToString();
}</set-body>
</return-response>
</when>
</choose>

Related

HTML templates could not be found in Production (NET Core 3.1)

I have a web application that is supposed to send verification emails to users upon signing up. I am using email templates that reside in a folder(EmailTemplate) under the root directory like so.
The problem is when I deploy the release on Google Cloud Platform I get this error when signing up
The templates are working fine in localhost debug testing but not in cloud testing.
.csproj file
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>removed intentionally</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<None Include="app.yaml" CopyToOutputDirectory="Always" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Repos\**" />
<Content Remove="Repos\**" />
<EmbeddedResource Remove="Repos\**" />
<None Remove="Repos\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.21" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.1.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.21">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="3.1.15" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.5" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.5" />
</ItemGroup>
</Project>
Email service that is using the templates
public class EmailService : IEmailService
{
private const string templatePath = #"EmailTemplate/{0}.html";
private readonly SMTPConfigModel _smtpConfig;
public EmailService(IOptions<SMTPConfigModel> smtpConfig)
{
_smtpConfig = smtpConfig.Value;
}
public async Task SendTestEmail(EmailDataModel testEmailModel)
{
testEmailModel.Subject = FillPlaceholders("Hello {{UserName}} this test subject", testEmailModel.PlaceHolders);
testEmailModel.Body = FillPlaceholders(EmailBodyTemplateGetter("TestEmail"), testEmailModel.PlaceHolders);
await SendEmail(testEmailModel);
}
public async Task SendVerificationEmail(EmailDataModel emailVerifyModel)
{
emailVerifyModel.Subject = FillPlaceholders("Please verify your email", emailVerifyModel.PlaceHolders);
emailVerifyModel.Body = FillPlaceholders(EmailBodyTemplateGetter("EmailVerification"), emailVerifyModel.PlaceHolders);
await SendEmail(emailVerifyModel);
}
private async Task SendEmail(EmailDataModel email)
{
MailMessage mail = new MailMessage
{
Subject = email.Subject,
Body = email.Body,
From = new MailAddress(_smtpConfig.SenderAddress, _smtpConfig.SenderDisplayName),
IsBodyHtml = _smtpConfig.IsBodyHTML
};
foreach (var item in email.ToEmails)
mail.To.Add(item);
NetworkCredential networkCredential = new NetworkCredential(_smtpConfig.UserName, _smtpConfig.Password);
SmtpClient smtpClient = new SmtpClient
{
Host = _smtpConfig.Host,
Port = _smtpConfig.Port,
EnableSsl = _smtpConfig.EnableSSL,
UseDefaultCredentials = _smtpConfig.UseDefaultCredentials,
Credentials = networkCredential
};
mail.BodyEncoding = Encoding.Default;
await smtpClient.SendMailAsync(mail);
}
private string EmailBodyTemplateGetter(string templateName)
{
=========> string filepath = string.Format(templatePath, templateName); <==========
var body = File.ReadAllText(filepath);
return body;
}
private string FillPlaceholders(string text, List<KeyValuePair<string, string>> keyValuePairs)
{
if (!string.IsNullOrEmpty(text) && keyValuePairs != null)
foreach (var placeholder in keyValuePairs)
if (text.Contains(placeholder.Key))
text = text.Replace(placeholder.Key, placeholder.Value);
return text;
}
}
Calling method in class Register.cs
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new PtUser { UserName = Input.Email, Email = Input.Email, FirstName = Input.FirstName, LastName = Input.LastName };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
EmailDataModel emailDataModel = new EmailDataModel()
{
ToEmails = new List<string>() { Input.Email },
PlaceHolders = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("{{UserName}}", user.FirstName),
new KeyValuePair<string, string>("{{Link}}", callbackUrl)
}
};
=======> await _emailService.SendVerificationEmail(emailDataModel); <============
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
As per asp.net core 3.1 static files are accessible via a path relative to the web root. So any files outside of the wwwroot cannot be accessed in production. In that case you have to move your EmailTemplate folder inside the wwwroot as you can see the picture below:
And then in Startup.Configure you have to add reference of this
middleware app.UseStaticFiles(); while you would browse the directory you have to modify code like this way
Note: In that case your path would be like
wwwroot/EmailTemplate/EmailTemplate.html and your code should be like
: private const string templatePath = #"wwwroot/EmailTemplate/{0}.html";
Hope above steps guided you accordingly.

How to parse array of json objects to custom XML (node.js)

I'm trying to use js2xmlparser (node.js) to transform an array of JSON objects into a custom XML file.
The source array looks like this:
[
{
"ID": "3233705000002165882",
"Quarter": "2020Q3",
"Pkg_Total": "0.00",
"Course_Each": "0.00"
},
{
"ID": "3233705000002165883",
"Quarter": "2020Q4",
"Pkg_Total": "2.50",
"Course_Each": "0.70"
},
{
"ID": "3233705000002165884",
"Quarter": "2021Q1",
"Pkg_Total": "34.00",
"Course_Each": "15.00"
}
]
I need the target XML to look like this:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<records>
<record id="3233705000002165882">
<column name="Quarter">
<value><![CDATA[2020Q3]]></value>
</column>
<column name="Pkg_Total">
<value><![CDATA[$ 0.00]]></value>
</column>
<column name="Course_Each">
<value><![CDATA[$ 0.00]]></value>
</column>
</<record>
<record id="3233705000002165883">
<column name="Quarter">
<value><![CDATA[2020Q4]]></value>
</column>
<column name="Pkg_Total">
<value><![CDATA[$ 2.50]]></value>
</column>
<column name="Course_Each">
<value><![CDATA[$ 0.70]]></value>
</column>
</<record>
<record id="3233705000002165884">
<column name="Quarter">
<value><![CDATA[2021Q1]]></value>
</column>
<column name="Pkg_Total">
<value><![CDATA[$ 34.00]]></value>
</column>
<column name="Course_Each">
<value><![CDATA[$ 15.00]]></value>
</column>
</<record>
</<records>
</response>
Any suggestions on how to configure js2xmlparser to do this? Or is there another node.js utility that can help with this transformation task? Thank you!
I solved this by writing my own custom function:
const json2XML = async (jsonFilePathName) => {
const jsonObj = await loadDataObj(jsonFilePathName)
let xmlRecords = '';
let xmlRecordBegin = '';
let xmlRecordFull;
jsonObj.forEach((newRecord) => {
const fieldNames = Object.keys(newRecord);
let colElements = '';
let colElement;
let colValue;
xmlRecordBegin = `<record id="${newRecord.ID}">`;
fieldNames.forEach((fieldName) => {
//iterate through all fieldNames except ID
if (fieldName !== 'ID') {
colValue = newRecord[fieldName];
colElement = `<column name="${fieldName}"><value><![CDATA[${colValue}]]></value></column>`;
colElements = colElements + colElement;
}
});
//end fieldNames.forEach((fieldName)
xmlRecordFull = xmlRecordBegin + colElements + '</record>';
//console.log('xmlRecordFull = ', xmlRecordFull);
xmlRecords = xmlRecords + xmlRecordFull;
});
//end jsonObj.forEach((newRecord)
xmlDoc = xmlDecl + xmlRootBegin + xmlRecordsBegin + xmlRecords + xmlRecordsEnd + xmlRootEnd;
return xmlDoc;
}

How to get value from response body in API management policy?

Im currently working with policys in Azure API Management and Im interesting in extracting a value that gets returned from the response-body.
<send-one-way-request mode="new">
<set-url>http://requestb.in/xje199xj</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
//JObject or string?
string response = context.Response.Body.As<string>(preserveContent: true);
//something here..
}
</set-body>
</send-one-way-request>
The response looks like this :
"getBookableResourcesResponse": {
"getBookableResourcesResult": {
"hasError": false,
"errorCode": 0,
"BookableResource": [
{
"resourceCode": "TRA",
"description": "Trailer",
"group": "F",
"subGroup": "C",
"category": "R",
"dialogType": "CARGO",
"orgCode": "DECK",
"length": 14,
"taraWeight": "7000",
"grossWeight": "25001",
"AddResource": [
{
"resourceCode": "EXPFIN",
"description": "Export Finland",
"dialogType": "UNDEFINED",
"amount": "0",
"ticketType": "",
"orgCode": "EXPFIN",
"required": "false"
}.....`
I want to get the value thats being returned from the "resourceCode" attribute, in this case "TRA" and then create a new JObject wich I can send to my Azure function.
{
"resourceCode": "valueFromResponseBody"
}
Instead of
string response = context.Response.Body.As<string>(preserveContent: true);
try:
var response = context.Response.Body.As<JObject>(preserveContent: true);
That would return Json.NET JObject (http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm) which you later can use to navigate your response.
My solution:
<send-one-way-request mode="new">
<set-url></set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
string xml = context.Response.Body.As<string>(preserveContent: true);
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList elemList = doc.DocumentElement.GetElementsByTagName("ResourceCode");
string allResources = string.Empty;
foreach (XmlNode item in elemList)
{
if (item.InnerText == "TRA" || item.InnerText == "CONT20" || item.InnerText == "CONT23" || item.InnerText == "CONT26" || item.InnerText == "CONT30" || item.InnerText == "CONT40" || item.InnerText == "CONT45" || item.InnerText == "TRUCK"|| item.InnerText == "VAN" || item.InnerText == "CAMP" || item.InnerText == "CAR")
{
allResources += item.InnerText + ",";
}
}
allResources = allResources.Substring(0, allResources.Length - 1);
return new JObject(new JProperty("resourceCode", allResources)).ToString();
}</set-body>
</send-one-way-request>
Ran into the same issue. The typical JsonConvert.SerializeXmlNode method isn't allowed in policy expressions.
However good ol' JsonConvert.SerializeObject did the trick.
<send-one-way-request mode="new">
<set-url>http://requestb.in/xje199xj</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
string xml = context.Response.Body.As<string>(preserveContent: true);
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
return JsonConvert.SerializeObject(doc);
}
</set-body>
</send-one-way-request>

sapui5 data from json

Have problem to read data from json. My login.json file
{
"Users": [
{
"login" : "admin",
"password" : "admin"
}
]
}
Here is my login.xml.view
<core:View
controllerName="sap.ui.demo.myFiori.view.login"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:core="sap.ui.core" >
<Page
title="{i18n>LoginIn}">
<VBox
class="marginBoxContent" >
<items>
<Label text="User" />
<Input
id="nameInput"
type="Text"
placeholder="..." />
<Label text="password" />
<Input
id="passwInput"
type="Password"
placeholder=" ..." />
<Text id="description" class="marginOnlyTop" />
<Button text="Login" press="handleContinue" />
</items>
</VBox>
</Page>
</core:View>
and login.controller.js
jQuery.sap.require("sap.ui.demo.myFiori.util.Formatter");
sap.ui.controller("sap.ui.demo.myFiori.view.login", {
handleContinue : function (evt) {
var name = this.getView().byId("nameInput").getValue();
var paswd = this.getView().byId("passwInput").getValue();
if (name == "log" && paswd == "pass") {
var context = evt.getSource().getBindingContext();
this.nav.to("Master", context);
}
else {
jQuery.sap.require("sap.m.MessageToast");
sap.m.MessageToast.show("Wrong login");
}
}
});
This login screen works, but I can't get login and password from json file and currently these data are taken from if sentence, which is not good. Any suggestions?
First, I am assuming that this is just a test app, as having the correct plain text auth credentials actually in the client app is rather bad practice ...
The crux of your question seems to be: "How can I access JSON data from a file?"
There is a Q&A already on SO with that theme: How to get data from a json file? but if you want to use a model, which is a common practice in UI5 apps, then you could:
1) Create a JSON model, specifying the name of the JSON file; the JSONModel mechanism will take care of the loading; assign this to the view
this.getView().setModel(new sap.ui.model.json.JSONModel('login.json'), "login");
2) Access the data in the JSON model when you need to check, using the getData() method
// Note - extremely bad practice - don't do this for real!
var authinfo = this.getView().getModel("login").getData().Users[0];
if (name == authinfo.login && paswd == authinfo.password) {
....
(I'm indexing 0 of Users as you seem to have your authinfo inside an array)
Maybe I defined something wrong before but now it works. I changed login.controller.js. Now it looks like this:
jQuery.sap.require("sap.ui.demo.myFiori.util.Formatter");
sap.ui.controller("sap.ui.demo.myFiori.view.login", {
onInit: function () {
var oModels = new sap.ui.model.json.JSONModel("login.json");
sap.ui.getCore().setModel(oModels);
},
handleContinue : function (evt) {
var authinfo = this.getView().getModel().getData().Users[0];
var name = this.getView().byId("nameInput").getValue();
var paswd = this.getView().byId("passwInput").getValue();
if (name == authinfo.login && paswd == authinfo.passw) {
var context = evt.getSource().getBindingContext();
this.nav.to("Master", context);
}
else {
jQuery.sap.require("sap.m.MessageToast");
sap.m.MessageToast.show("Wrong login");
}
}
});

Using Google Maps API to get Address of Business

I have a requirement and I am hoping Google Maps API will have a solution. I have never used Google Maps API - so I am very new to this.
On the website homepage there is a form, when a user comes, I want the following things to happen:
1) The city field should be populated with users city based on IP
2) There is a second field called store name - when the user starts typing the store name - I want to fetch all business listings with that name in that city and show it as a drop down from which the user can select the appropriate branch. There is no need for anything to be shown on the map.
Egs - If a user in houston starts typing McDonalds, the following business listings should start showing up
McDonalds, 12 Pearland Ave, Houston TX
McDonalds, 2600 Bary Area Blvd, Houston TX
McDonalds, 262 Clearlake Blvd, Houston TX
Also when we get the address for a business listing from Google API - do we get it as one String and we need to parse it or do we get it different fields Street Name, City, State, Zip code etc
Any information or examples will be really appreciated
Thanks
I don't think you want Google Maps. First of all the terms of use do not allow any use other than displaying things on a Google Map on a publicly accessible webpage, second, there is another Google API that does exactly what you need: the Client location API: http://code.google.com/apis/ajax/documentation/#ClientLocation
Concerning the "businesses": You're going to have to source that data from somewhere - I do not believe google has a service for that. Perhaps you could simply use the Google Search API and some logic to find only businesses (http://code.google.com/apis/ajaxsearch/)
EDIT: I for the businesses, perhaps you could take a look at this sample: http://code.google.com/apis/ajaxsearch/samples.html#local-search
updated: here is an example of using the google clientlocation api and localsearch using jsonp.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAALDWeTDQHOJCbCf0JnUqL8BT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQA7AE8xB9MyWgHECPY2qimOp7BUQ"></script>
<script src="scripts/clientLocation.js" type="text/javascript"></script>
<script src="scripts/localSearch.js" type="text/javascript"></script>
<script type="text/javascript">
function $g(id) {
return document.getElementById(id);
}
function displayLocation(latitudeEl, longitudeEl, cityEl, regionEl, countryEl, country_codeEl) {
var cloc = new ClientLocation.Location(google.loader.ClientLocation);
if (latitudeEl) latitudeEl.innerHTML = cloc.latitude;
if (longitudeEl) longitudeEl.innerHTML = cloc.longitude;
if (cityEl) cityEl.innerHTML = cloc.address.city;
if (regionEl) regionEl.innerHTML = cloc.address.region;
if (country) country.innerHTML = cloc.address.country;
if (country_codeEl) country_codeEl.innerHTML = cloc.address.country_code;
}
function localSearch(term, callback, context) {
var cloc = new ClientLocation.Location(google.loader.ClientLocation);
var searchUrl = 'http://www.google.com/uds/GlocalSearch?callback=' + callback + '&context=' + context + '&hl=en&q=' + encodeURIComponent(term) + '&sll=' + cloc.latitude + ',' + cloc.longitude + '&key=ABQIAAAALDWeTDQHOJCbCf0JnUqL8BT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQA7AE8xB9MyWgHECPY2qimOp7BUQ&v=1.0';
// http://jaybyjayfresh.com/2007/09/17/using-script-tags-to-do-remote-http-calls-in-javascript/
scriptLoaded = function() {
removeNode(newScript);
};
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.onload = scriptLoaded;
newScript.src = searchUrl;
headID.appendChild(newScript);
}
function search() {
var term = $g("txtSearch").value;
localSearch(term, "displayResults", "0");
}
function displayResults(context, results, status, details, unused) {
var titles = [];
for (var i = 0; i < results.results.length; i++) {
// this cast is not necessary, just here to illustrate
// vs intellisense and reduce coding errors.
var result = new LocalSearch.Result(results.results[i]);
titles.push(result.title);
}
$g("searchResults").innerHTML = titles.join("</br>");
}
function init() {
displayLocation($g("latitude"), $g("longitude"), $g("city"), $g("region"), $g("country"), $g("country_code"));
}
</script>
</head>
<body onload="init()">
<form id="form1" runat="server">
<div>
latitude : <span id="latitude"></span>
<br />
longitude : <span id="longitude"></span>
<br />
city : <span id="city"></span>
<br />
region : <span id="region"></span>
<br />
country : <span id="country"></span>
<br />
country_code : <span id="country_code"></span>
<br />
</div>
<input type="text" id="txtSearch" /><input type="button" id="btnSearch" value="get results"
onclick="search();" /><br />
<div id="searchResults">
</div>
</form>
</body>
</html>
// <copyright file="clientLocation.js" company="Sky Sanders">
// This source is placed in the Public Domain.
// http://skysanders.net/subtext
// Attribution is appreciated.
// </copyright>
/*
object literal format for google.loader.clientlocation
{
"latitude": 33.324,
"longitude": -111.867,
"address": {
"city": "Chandler",
"region": "AZ",
"country": "USA",
"country_code": "US"
}
}
*/
var ClientLocation = {};
ClientLocation.Address = function() {
/// <field name="city" type="String" />
/// <field name="region" type="String" />
/// <field name="country" type="String" />
/// <field name="country_code" type="String" />
/// <returns type="ClientLocation.Address"/>
if (arguments.length > 0) {
this.city = arguments[0].city;
this.region = arguments[0].region;
this.country = arguments[0].country;
this.country_code = arguments[0].country_code;
return;
}
else {
this.city = "";
this.region = "";
this.country = "";
this.country_code = "";
}
}
ClientLocation.Location = function() {
/// <field name="latitude" type="Number" />
/// <field name="longitude" type="Number" />
/// <field name="address" type="ClientLocation.Address" />
if (arguments.length > 0) {
this.latitude = arguments[0].latitude;
this.longitude = arguments[0].longitude;
this.address = arguments[0].address;
}
else {
this.latitude = 0;
this.longitude = 0;
this.address = undefined;
}
}
// <copyright file="localSearc.js" company="Sky Sanders">
// This source is placed in the Public Domain.
// http://skysanders.net/subtext
// Attribution is appreciated.
// </copyright>
/*
GlocalSearch result
{
"GsearchResultClass": "GlocalSearch",
"viewportmode": "computed",
"listingType": "local",
"lat": "33.389689",
"lng": "-111.853909",
"accuracy": "8",
"title": "Best \u003cb\u003eBuy\u003c/b\u003e",
"titleNoFormatting": "Best Buy",
"ddUrl": "http://www.google.com/maps....",
"ddUrlToHere": "http://www.google.com/maps?....",
"ddUrlFromHere": "http://www.google.com/maps?....",
"streetAddress": "1337 South Alma School Road",
"city": "Mesa",
"region": "AZ",
"country": "United States",
"staticMapUrl": "http://mt.google.com/mapdata?....",
"url": "http://www.google.com/maps/place?source....",
"content": "",
"maxAge": 604800,
"phoneNumbers": [{
"type": "",
"number": "(480) 644-7139"
},
{
"type": "",
"number": "(480) 464-0444"
}],
"addressLines": ["1337 South Alma School Road", "Mesa, AZ"]
}
*/
var LocalSearch = {};
LocalSearch.PhoneNumber = function() {
/// <field name="type" type="String"/>
/// <field name="number" type="String"/>
/// <returns type="LocalSearch.PhoneNumber"/>
if (arguments.length > 0) {
this.type = arguments[0].type;
this.number = arguments[0].number;
}
else {
this.type = "";
this.number = "";
}
}
LocalSearch.Result = function() {
/// <field name="GsearchResultClass" type="String"/>
/// <field name="viewportmode" type="String"/>
/// <field name="listingType" type="String"/>
/// <field name="lat" type="String"/>
/// <field name="lng" type="String"/>
/// <field name="accuracy" type="String"/>
/// <field name="title" type="String"/>
/// <field name="titleNoFormatting" type="String"/>
/// <field name="ddUrl" type="String"/>
/// <field name="ddUrlToHere" type="String"/>
/// <field name="ddUrlFromHere" type="String"/>
/// <field name="streetAddress" type="String"/>
/// <field name="city" type="String"/>
/// <field name="region" type="String"/>
/// <field name="country" type="String"/>
/// <field name="staticMapUrl" type="String"/>
/// <field name="url" type="String"/>
/// <field name="content" type="String"/>
/// <field name="maxAge" type="Number"/>
/// <field name="phoneNumbers" type="Array"/>
/// <field name="addressLines" type="Array"/>
// <returns type="LocalSearch.Result"/>
if (arguments.length > 0) {
this.GsearchResultClass = arguments[0].GsearchResultClass;
this.viewportmode = arguments[0].viewportmode;
this.listingType = arguments[0].listingType;
this.lat = arguments[0].lat;
this.lng = arguments[0].lng;
this.accuracy = arguments[0].accuracy;
this.title = arguments[0].title;
this.titleNoFormatting = arguments[0].titleNoFormatting;
this.ddUrl = arguments[0].ddUrl;
this.ddUrlToHere = arguments[0].ddUrlToHere;
this.ddUrlFromHere = arguments[0].ddUrlFromHere;
this.streetAddress = arguments[0].streetAddress;
this.city = arguments[0].city;
this.region = arguments[0].region;
this.country = arguments[0].country;
this.staticMapUrl = arguments[0].staticMapUrl;
this.url = arguments[0].url;
this.content = arguments[0].content;
this.maxAge = arguments[0].maxAge;
this.phoneNumbers = arguments[0].phoneNumbers;
this.addressLines = arguments[0].addressLines;
}
else {
this.GsearchResultClass = "";
this.viewportmode = "";
this.listingType = "";
this.lat = "";
this.lng = "";
this.accuracy = "";
this.title = "";
this.titleNoFormatting = "";
this.ddUrl = "";
this.ddUrlToHere = "";
this.ddUrlFromHere = "";
this.streetAddress = "";
this.city = "";
this.region = "";
this.country = "";
this.staticMapUrl = "";
this.url = "";
this.content = "";
this.maxAge = 0;
this.phoneNumbers = [];
this.addressLines = [];
}
}
If you're only looking up restaurants, try using Yelp's API. You can search for a business by its name within a search radius. Their API is also simpler and easier to use than google's.
http://www.yelp.com/developers/documentation/search_api