I'm trying to use Maps API from my mobile application in a similar manner as I can do using my Firefox browser:
http://maps.googleapis.com/maps/api/geocode/json?address=First Avenue New York Manhattan&sensor=true
Unfortunately, I always receive this error result: The 'sensor' parameter specified in the request must be set to either 'true' or 'false'
I tried TRUE, True, true... no way.
I also tried to use my API Key associated to my google account following this guide: https://developers.google.com/maps/documentation/javascript/tutorial?hl=it#api_key
In fact, I did:
http://maps.googleapis.com/maps/api/geocode/json?key={my_key}&address=First Avenue New York Manhattan&sensor=true
So, finally, I suppose my problems are related to the POST Request I prepared.
This is the code I use for my Request:
request = new CIwHTTP; // The http pointer
const char* c1 = text.getCString(); // This is the string "address=First Avenue New York Manhattan&sensor=true"
int length = strlen(c1);
request->SetRequestHeader("Content-Type", "text/javascript; charset=utf-8");
request->Post("http://maps.googleapis.com/maps/api/geocode/json", c1, length, callback, NULL);
In the callback I got my result string, hopefully the JSON string coming from Google telling me the address list. I'm not so sure about the Header, but I changed few of them without results.
I use Marmalade, so my code is fully C++.
Could you help me?
It seems Google doesn't like spaces in the address string and the call should be a GET call.
This is my working code:
CCString gURL = "http://maps.googleapis.com/maps/api/geocode/json?"; // URL base
CCString *string_final = CCString::createWithFormat( (
std::string(gURL.getCString()) +
std::string(text.getCString()) /* i.e. "address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false" */
).c_str() );
request->Get(string_final->getCString(),callback, NULL);
Related
First timer when it comes to connecting to API. I'm trying to pull data from Toggl using my API token but I can't get credentials working. I tried to replicate the method by Chris Webb (https://blog.crossjoin.co.uk/2014/03/26/working-with-web-services-in-power-query/) but I can't get it working. Here's my M code:
let
Source = Web.Contents(
"https://toggl.com/reports/api/v2/details?workspace_id=xxxxx&client=xxxxxx6&billable=yes&user_agent=xxxxxxx",
[
Query=[ #"filter"="", #"orderBy"=""],
ApiKeyName="api-token"
])
in
Source
After that I'm inputting my API Token into Web API method in Access Web content windows but I get an error that credentials could not be authenticated. Here's Toggl API specification:
https://github.com/toggl/toggl_api_docs/blob/master/reports.md
Web.Contents function receives two parameters: url + options
Inside options, you define the headers and the api_key, and other queryable properties, such as:
let
baseUrl = "https://toggl.com/",
// the token part can vary depending on the requisites of the API
accessToken = "Bearer" & "insert api token here"
options = [
Headers = [Authorization = accessToken, #"Content-Type" =
"application/Json"], RelativePath ="reports/api/v2/details", Query =
[workspace_id=xxxxx, client=xxxxxx6 , billable=yes, user_agent=xxxxxxx]
]
Source = Web.Contents(baseUrl, options)
// since Web.Contents() doesn't parse the binaries it fetches, you must use another
// function to see if the data was retreived, based on the datatype of the data
parsedData = Json.Document(Source)
in
parsedData
The baseUrl is the smallest url that works and never changes;
The RelativePath is the next part of the url before the first "?".
The Query record is where you define all the attributes to query as a record.
This is usually the format, but check the documentation of the API you're querying to see if it is similar.
I am using Angular4 with TypeScript version 2.2.2
My web app is running fine when I call JSON with Filters but my NativeScript app fails when I call the Filter Values as an Object but works fine when I call filter values as a string.
Error Response with status: 200 for URL: null
THIS WORKS
https://domainname.com/api/v1/searchevents?token=057001a78b8a7e5f38aaf8a682c05c414de4eb20&filter=text&search=upcoming
If the filter value and search value is STRING it works whereas if they are objects as below, it does not work
THIS DOES NOT WORK
https://api.domainname.com/api/v1/searchevents?token=057001a78b8a7e5f38aaf8a682c05c414de4eb20&filter={"limit":"12","skip":"0"}&search={"search":"","latitude":"","longitude":"","categories":"","address":"","type":"upcoming"}
The Code I used is below
getData(serverUrl, type, skip_limit) {
console.log(serverUrl);
let headers = this.createRequestHeader();
let token_value = localStorage.getItem('access_token')
let url;
var filter;
filter = '{"limit":"10","skip":"0"}'
url = this.apiUrl + serverUrl + '?token=' + token_value + '&filter=' + filter
return this.http.get(url, { headers: headers })
.map(res => res.json());
}
The URL as formed above for the API is fine and works fine. Yet the error comes Error Response with status: 200 for URL: null
CAN ANYONE HELP ME SOLVE THIS?
Looks like the issue is the "filter" values are of different type and from what you mentioned as what worked, your service is expecting a string and not an object/array. So it fails to send the proper response when it gets one. With an object in the URL, you may have to rewrite the service to read it as an object (parse the two attributes and get them individually)
To make it simple, you can make these two as two different variables in the URL. like below,
https://api.domainName.in/api/v1/oauth/token?limit=10&skip=0
Be more precise in whats happening in your question,
1) Log the exact URL and post it in the question. No one can guess what goes in "text" in your first URL.
2) Your URL which you mentioned as worked have "token" as part of path, but in the code, its a variable which will have a dynamic value from "token_value".
3) Post your service code. Especially the signature and input parsing part.
Got the solution:
All you have to do is encode the Filter and Search Parameters if it is an Object or Array using Typescript encodeURI()
var filter = '{"limit":"12","skip":"0"}'
var search = '{"search":"","latitude":"","longitude":"","categories":"","address":"","type":"upcoming"}'
var encoded_filter = encodeURI(filter);
var encoded_search = encodeURI(search);
url = this.apiUrl+serverUrl+'?token='+token_value+'&filter='+encoded_filter+'&search='+encoded_search
What would be a good way to work with Chrome's incoming 1MB limit for native messaging extensions? The data that we would be sending to the extension is json-serialized gpx, if that matters.
When the original message is >1MB, it seems like this question really has two parts:
how to partition the data on the sending end (i.e. the client)
this part should be pretty trivial. Even if we need to split into separate self-contained complete gpx strings, that is pretty straightforward.
how to join the <1MB messages back in to the original >1MB
is there a standard known solution for this question? We can call background.js (ie. the function passed to chrome.runtime.onMessageExternal.addListener) once for each <1MB incoming message, but, how would we combine the strings from those repeated calls in to one response for the extension?
UPDATE 8-18-16:
what we've been doing is just appending each message 'chunk' on a buffer variable in background.js, and not send it back to Chrome until disconnection:
var gpxText="";
port.onMessage.addListener(function(msg) {
// msg must be a JSON-serialized simple string;
// append each incoming msg to the collective gpxText string
// but do not send it to Chrome until disconnection
// console.log("received " + msg);
gpxText+=msg;
});
port.onDisconnect.addListener(function(msg) {
if (gpxText!="") {
sendResponse(JSON.parse(gpxText));
gpxText="";
} else {
sendResponse({status: 'error', message: 'something really bad happened'});
}
// build the response object here with msg, status, error tokens, and always send it
console.log("disconnected");
});
We will have to make that appending a bit smarter to handle and send both status and message keys/values, but that should be easy.
I have this same issue and have been scouring the web for the past couple days to figure out something to do. In my application, I am currently shipping a JSON string over to the background script in chunks, having to create a subprotocol to handle this special case. e.g. my initial question might look like:
{action:"getImage",guid:"123"}
and the response for <1MB might look like:
{action:"getImage",guid:"123",status:"success",return:"ABBA..."}
where ABBA... represents a base64 encoding of the bytes. when >1MB, however, the response will look like:
{action:"getStream",guid:"123",status:"success",return:"{action:\"getImage\",guid:\"123\",return:\"ABBA...",more:true}
and upon receipt of the payload with method==='stream', the background page will immediately issue a new request like:
{action:"getStream",guid:"123"}
and the next response might look like:
{action:"getStream",guid:"123",status:"success",return:"...DEAF==",more:false}
so your onMessage handler would look something like:
var streams;
function onMessage( e ) {
var guid = e.guid;
if ( e.action === 'getStream' ) {
if ( !streams[ guid ] ) streams[ guid ] = '';
streams[ guid ] += e[ 'return' ];
if ( e.more ) {
postMessage( { action: 'getStream', guid: guid } );
// no more processing to do here, bail
return;
}
e = JSON.parse( streams[ guid ] );
streams[ guid ] = null;
}
// do something with e as if it was never chunked
...
}
it works, but I am somewhat convinced that it is slower than it should be (though this could be due to the slow feeling of the STDIO signaling and, in my particular app, additional signaling that has to happen for each new chunk).
Ideally I'd like to stream the file in a more efficient protocol supported natively by Chrome. I looked into WebRTC, but it would mean that I'd need to implement the API into my native messaging host (as best I can tell), which is not an option I'm willing to take on. I played with 'passing' the contents by file as such:
if ( e.action = 'getFile' ) {
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function( e ) {
if ( e.target.readyState === 4 ) {
onMessage( e.target.responseText );
}
};
xhr.open( 'GET', chrome.extension.getURL( '/' + e.file ), true );
xhr.send();
return;
}
where I have my native message host write a .json file out to extension's install directory and it seems to work, but there is no way for me to reliably derive the path (without fudging things and hoping for the best), because as best I can the location of the extensions install path is determined by your Chrome user profile and there's no API I could find to give me that path. Additionally, there's a 'version' folder created under your extension id which includes an _0 that I don't know how to calculate (is the _0 constant for some future use? does it tick up when an extension is published anew to the web store, but the version is not adjusted?).
At this point I'm out of ideas and I'm hoping someone will stumble across this question with some guidance.
I'm using Ember-Data 1.0.0.Beta-9 and Ember 1.7 to consume a REST API via DreamFactory's REST Platform. (http://www.dreamfactory.com).
I've had to extend the RESTAdapter in order to use DF and I've been able to implement GET and POST requests with no problems. I am now trying to implement model.save() (PUT) requests and am having a serious hiccup.
Calling model.save() sends the PUT request with the correct data to my API endpoint and I get a 200 OK response with a JSON response of { "id": "1" } which is what is supposed to happen. However when I try to access the updated record all of the properties are empty except for ID and the record on the server is not updated. I can take the same JSON string passed in the request, paste it into the DreamFactory Swagger API Docs and it works no problem - response is good and the record is updated on the DB.
I've created a JSBin to show all of the code at http://emberjs.jsbin.com/nagoga/1/edit
Unfortunately I can't have a live example as the servers in question are locked down to only accept requests from our company's public IP range.
DreamFactory provides a live demo of the API in question at
https://dsp-sandman1.cloud.dreamfactory.com/swagger/#!/db/replaceRecordsByIds
OK in the end I discovered that you can customize the DreamFactory response by adding a ?fields=* param to the end of the PUT request. I monkey-patched that into my updateRecord method using the following:
updateRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record);
var adapter = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
// hack to make DSP send back the full object
adapter.ajax(adapter.buildURL(type.typeKey) + '?fields=*', "PUT", { data: data }).then(function(json){
// if the request is a success we'll return the same data we passed in
resolve(json);
}, function(reason){
reject(reason.responseJSON);
});
});
}
And poof we haz updates!
DreamFactory has support for tacking several params onto the end of the requests to fully customize the response - at some point I will look to implement this correctly but for the time being I can move forward with my project. Yay!
EmberData is interpreting the response from the server as an empty object with an id of "1" an no other properties in it. You need to return the entire new object back from the server with the changes reflected.
I am making an extension (A) for Chrome that communicates with another extension (B). I want A to provide the B a function, but it won't send. I can send strings just fine.
A has the following code. rect is the function in this code.
chrome.extension.onRequestExternal.addListener(
function(request, sender, sendResponse) {
obj = {}
obj.permisions = "all"
obj.rect = Rect
alert(obj.permisions+","+obj.rect)
sendResponse(obj);
});
...this code works just fine. The alert shows a box that says "all", then prints out the function.
B has the following code.
chrome.extension.sendRequest(ext[i].id, {}, function(lib) {
alert(lib.permisions+","+lib.rect)
});
The alert on this one shows "all,undefined". Can functions not be passed between extensions?
While you can certainly communicate between extensions, you can only pass valid JSON. Unfortunately, valid JSON only includes simple data types(String, Number, Boolean, Array, Object* or Null).
One way to do it would be to pass the function as a String and use eval on the receiving end. Could be unsafe, but is doable.
* While a function is technically an Object, in this context Object refers to name:value pairs of the aforementioned simple data types.