Get Google Place Details Without Map - google-places-api

I have a reference to a Google Place, and use the Javascript API to get the place details.
It works fine as long as there is a map on the page.
But if there is no map - I only want the place's details - it breaks because the variable map is not defined.
The documentation specifies:
"Place Details are requested with a call to the service's getDetails() method."
service = new google.maps.places.PlacesService(map);
service.getDetails(request, callback);
If I leave out the map variable, I get: "Uncaught TypeError: Cannot read property 'innerHTML' of undefined"
I can make a server-side request, but there is a limit to the number of times you can do that.
Is there a way in Javascript to get just the place details without a map?

After working with this for a bit, the solution I came up with was to create a new map object without appending it to the document. The API seems to be fine with this.
let map = new google.maps.Map(document.createElement('div'));
Then make your request, same as before with the dummy map obj.
this.googlePlaces = new google.maps.places.PlacesService(map);
this.googlePlaces.getDetails(request, callback);

Related

Laravel - retrieve data inside controller – POST x PATCH

First important information: I’m new to laravel, so your patience is appreciated.
I’m currently migrating a framework of mine to laravel, so I’m in the early stages.
Currently, I’m trying to set up an API endpoint to make small changes on some records. I’ve already managed to set up a API for inserting records and works perfectly. However, for setting up an API for small changes (patch), I’m having difficulties, probably because I’m not fully familiar with laravel’s Request class.
My successful insert set up looks like this:
\routes\api.php
Route::post('/categories/',[ApiCategoriesInsertController::class, 'insertCategories'], function($insertCategoriesResults) {
return response()->json($insertCategoriesResults);
})->name('api.categories.insert');
\app\Http\Controllers\ApiCategoriesInsertController.php
// some code
public function insertCategories(Request $req): array
{
$this->arrCategoriesInsertParameters['_tblCategoriesIdParent'] = $req->post('id_parent');
// some code
}
With this set up, I’m able to retrieve “id_parent” data set through POST.
So, I tried to do exactly the same architecture for patch, but doesn’t seem to work:
\routes\api.php
Route::patch('/records/',[ApiRecordsPatchController::class, 'patchRecords'], function($patchRecordsResults) {
return response()->json($patchRecordsResults);
})->name('api.records.patch');
\app\Http\Controllers\ApiRecordsPatchController.php
// some code
public function patchRecords(Request $req): array
{
$this->arrRecordsPatchParameters['_strTable'] = $req->post('strTable');
// some code
}
In this case, I´m using postman (PATCH request), testing the data in the "Body tab" with key "strTable" and value "123xxx" and I´m receiving “strTable” as null.
Any idea of why this is happening or if I should use another method in the Request class?
Thanks!
You can access parameters on the Request object using one of the following methods:
$req->strTable;
// or
$req->input('strTable');
The input method also accepts a second parameter which will be used as the default return value if the key is not present in the Request.
If you want to check whether or not the Request contains a value before you attempt to access it, you can use filled:
if ($req->filled('strTable')) {
// The request contains a value
}
Turns out that the way I had set up was in fact working and retrieving data:
$req->post('strTable');
The problem was in how I was testing it. In postman, there are several options to configure:
form-data
x-www-form-urlencoded
raw
binary
I had already switched to x-www-form-urlencoded to test it, but I forgot to fill the “key” and “value” information again. I didn’t realize that the fields blank as we switch between them.
Summing it up: It works when x-www-form-urlencoded selected but doesn’t work with form-data selected. Don’t know what the difference between them yet, but I’ll research it further.
By the way, it worked also with the suggestion from Rube Hart:

Unable to access POST parameter values - IIB Esql

So I'm quite new to IIB and Extended SQL but what I want to do should be straight forward. I have a REST application which has a resource that is attached to a subflow. What I want to do is to get the input value passed to the service and use it to call a remote web service using the HTTP request node as shown below
SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = 'POST';
SET OutputLocalEnvironment.Destination.HTTP.RequestURL = 'http://localhost:8002/MyService';
SET OutputLocalEnvironment.Destination.HTTP.QueryString.RemoteParam= InputLocalEnvironment.REST.Input.Parameters.myValue;
What is happening is, when I call the REST method and pass the value as a GET, I'm able to access the value. However, when I pass the parameter value using POST, I'm unable to access the value. My current flow is as follows:
Input > Compute > HTTPRequest > Compute > Output
I have searched on Google and applied all recommendations (e.g. setting compute node to LocalEnvironment) but nothing seems to work.
Well, we need more information in order to solve your problem but I guess you have problem in your HTTP request node
Go to HTTP request then in properties go to HTTP setting and change HTTP method to the method that you are using ( get or post )
and if you want to see if you are fetching data from right property just lunch debugger and put breakepoint in before and after of your nodes, then you can see what data you are receiving in each level and you can call the proper property.
ps. don't forget to deploy your project again in order to see new
changes
I hope that works for you
After further research, I found that IIB does not automatically parse content submitted as application/x-www-form-urlencoded. I inserted a trace node and realised that the parameters are instead submitted as a BLOB. All I had to do was read the blob, cast it to a string then use a Split function or a message model to get the individual parameters. Thanks for the pointers

DocumentNode.SelectSingleNode return null

I want to get the time of this url "https://www.toutiao.com/a6619068128406028804/" with the HtmlAgilityPack, my code is as following:
string url = "https://www.toutiao.com/a6619068128406028804/"
HtmlWeb web = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = web.Load(url);
HtmlNode node_time= doc.DocumentNode.SelectSingleNode("/html/body/div[1]/div[2]/div[2]/div[1]/div[1]/span[2]");
time = node_time.InnerText.Trim();
node_time is always being null, how can I get the content of the time tag?
The problem is not the xPath selector, it's the fact that those elements are rendered client side. If you look at the actual initial get request (can do this in chrome/fiddler/ext) you see that those elements are not there. However there is a "articleInfo" json object inside of the "BASE_DATA" json string that is sent back. Normally you want to parse out that string and then deserialize it, then you have a structured object to grab data from. I normally use visual studio paste as classes feature but this seems kind of complicated for that and is mostly outside of the scope of your issue with this.
Also to note the object does get loaded into javascript but you cannot access that with HAP, if you were using headless browsers you could access that object directly using the execute javascript features.
So basically you can either parse out the json string manually or switch to something like a headless browser where the javascript is actually executed.

How to inject a header from the errormessage

I've been attempting to inject a custom header for a error response status (and failing).
I have a very simple lambda being used
exports.handler = (event, context, callback) => {
// TODO implement
//callback(null, 'Hello from Lambda');
var error = {
name:"error",
message:"I am a failure",
statusCode: 400
};
error["x-test"] = 'foo';
callback(JSON.stringify(error), null);
};
In the api gateway, I've done the following:
set up CORS to include x-test
responsetemplate = "$input.path('$.errorMessage')"
responseparameter to include:
method.response.header.x-test = integration.response.body.x-test
Also, I have a statusCode mapped using '.*statusCode.*?400.*'
This has turned out empty.
so I decided to take a step back and see what happens if I do:
method.response.header.x-test = integration.response.body
I found that I get the stringified response of errorMessage.
{"x-test":"{\"errorMessage\":\"{\\\"name\\\":\\\"error\\\",\\\"message\\\":\\\"I am a failure\\\",\\\"statusCode\\\":400,\\\"x-test\\\":\\\"foo\\\"}\"}"}
So I decided to change the responsetemplate to force it to json by doing the following:
responsetemplate = "$util.parseJson($input.path('$.errorMessage'))"
and I still get the stringified response:
{"x-test":"{\"errorMessage\":\"{\\\"name\\\":\\\"error\\\",\\\"message\\\":\\\"I am a failure\\\",\\\"statusCode\\\":400,\\\"x-test\\\":\\\"foo\\\"}\"}"}
My guess is that it doesn't transform as expected, but only for the final output.
So how would you take a value and shove it into a header?
Thanks,
Kelly
I think this is more of a design choice regarding the limitation imposed by both Lambda and APIGateway. I will try my best to walk through my thoughts.
First of all, in Lambda, callback(error, result) function can either take an error string as first argument, or an object as result response. If you want to pass along a simple error message, you could definitely just do that. However, in your case, as you tried to pass along an entire error object, choosing the second option is clearly a better solution (in contrast to stringifying an object and parse it into object again). As a result, the final line of your Lambda function should be:
callback(null, error);
Yes, in this case, if you test your function in Lambda, the output result will no longer be red and flag it as an error, but this won't matter as you can format your headers and response in APIGateway.
Now you need to set things up in APIGateway, in which you need to make use of the object passed by Lambda.
It's actually rather easy to use method execution interface to configure headers.
In Method Response, you need to add the headers you want to include in the response for a specific status code, which in your case is x-test. (If you want the API to return different status codes, you can also configure that in this panel.)
Then go to Integration Response, under the same status code, you will see the added header available. According to this documentation from AWS, you can use integration.response.body.JSONPath_EXPRESSION to assign the header value (this is another reason that you should return object rather than string in Lambda, as there is no formal API to parse object from string at this stage). This time, as your Lambda is passing an object, the value of x-test header is:
integration.response.body['x-test']
Now your API should have the proper header included.
NOTE: In order to set up different status code in APIGateway, you should leave some distinguishable data fields (your statusCode: 400 should work perfectly) in you response body, so you can use RegEx to match those fields to a specific status code.
So... above doesn't work with success message. I found this blog though talking about error handling design pattern. Apparently what they suggest is only mapping status code when there is an error, in which case no body should be passed (only the errorMessage), as browser won't care about response body for a status code other than 200 anyway.
I guess after all, it is impossible to customize both status code and header at the same time with Lambda passing an object to APIGateway?
This is due to the fact that you are stringifying the error object coming from your Lambda function. API Gateway attempts to resolve the JSON-Path expression and can't evaluate "x-test" in a string. If you return an object instead of a string, this should work.
You may want to consider using proxy integrations which allow you to control the headers and status directly from your Lambda function.
Update: I've written a blog post on this topic with sample code # https://rpgreen.wordpress.com/2017/01/25/how-to-send-response-headers-for-aws-lambda-function-exceptions-in-api-gateway/

Partial markup via Tapestry block

I'm using Tapestry 5.3.
In a Tapestry component, I'm trying to implement an event handler that creates responses to AJAX requests.
I know that I can call MarkupWriterFactory#newPartialMarkupWriter to get an instance of MarkupWriter and then generate the response using this instance. The built-in mixin Autocomplete generates responses to AJAX requests in this way. Here is a trivial example:
#Inject
private MarkupWriterFactory markupWriterFactory;
#OnEvent("myevent")
Object generatePartialMarkup() {
final ContentType contentType = new ContentType("text/html");
final MarkupWriter markupWriter = markupWriterFactory.newPartialMarkupWriter(contentType);
markupWriter.element("hr");
markupWriter.end();
return new TextStreamResponse(contentType.toString(), markupWriter.toString());
}
However, this is a clumsy solution for a partial HTML that is much more complex than just a hr element. I wonder if there is a chance to create such response using a Tapestry block rather than generating the response "manually" via MarkupWriter. If I just return an instance of block from the event handler, an exception is thrown when the event is triggered.
Thanks.
Looks like you're making life difficult for yourself. From what I can see you can solve this with an eventlink, a zone and an event handler which returns a Block. See here for more info.
Not entirely sure what you're doing but if you need to render a block as a string, see the capture component here

Resources