Difference between fetch and $.getjson - javascript

I've been playing around with the Google+ API and trying to get the profile image url of a Google+ user with this url:
https://www.googleapis.com/plus/v1/people/{user_id}?key={API_KEY}
No OAuth is needed and you can also give it a try here (no API key needed):
https://developers.google.com/apis-explorer/#p/plus/v1/plus.people.get?userId=116725099929439898086&_h=1&
At first I used the Fetch API to fetch the data since I also want to use a service worker to do that:
fetch('https://www.googleapis.com/plus/v1/people/116725099929439898086?key=MY_API_KEY')
.then(function(response){
console.log(response);
});
But it only gives me this response:
{
body: ReadableStream
bodyUsed: false
headers: Headers
ok: true
status: 200
statusText: ""
type: "cors"
url: "https://www.googleapis.com/plus/v1/people/115681458968227650592?key=MY_API_KEY"
}
However, if I use jQuery's getJSON method instead:
$.getJSON( "https://www.googleapis.com/plus/v1/people/115681458968227650592?key=MY_API_KEY", function( data ) {
console.log(data);
});
It works like a charm and I can get what I need:
{
"kind": "plus#person",
"etag": "\"FT7X6cYw9BSnPtIywEFNNGVVdio/DgskSQn7XXHCvjcdFBFkiqEbsfo\"",
"gender": "male",
"urls": [ ... ],
"objectType": "person",
"id": "116725099929439898086",
"displayName": "Kevin Lai",
...
}
Can someone explain why they will to such different behaviors? And also, how can I fix the problem while still using the Fetch API so I can still do this asynchronous task in a service worker?

Change the fetch() call to use response.json() (see MDN docs) to extract the JSON from the response body.
fetch('https://www.googleapis.com/plus/v1/people/116725099929439898086?key=MY_API_KEY')
.then(function (response){
return response.json();
})
.then(function (json){
console.log(json);
});

Related

fetch() always results in "type: 'opaque'". But I can use Postman on my endpoint successfully

I must be really terrible at JavaScript but I've been struggling with this for a few days and I've not made any progress.
To make a long story short, I'm trying to work with UPS's REST API. I can do it with Postman and I can do it with PowerShell without any problems. JavaScript is a completely different story and I'm getting nowhere.
I've tried both XMLHttpRequest and fetch() and I've tried so many different combinations of things I can't begin to list them all.
Below is my JS function in my web app (it's triggered onchange of a field). The JS function makes a call to an Azure Function (the Azure Function works from Postman and from PowerShell.)
function getUpsShipTime() {
var jsonBody = {
"DeliveryDate": "2017-06-06",
"ShippingCode": "GND",
"ShipFrom": {
"Address": {
"StateProvinceCode": "CA",
"CountryCode": "US",
"PostalCode": "90210"
},
},
"ShipTo": {
"Address": {
"StateProvinceCode": "FL",
"CountryCode": "US",
"PostalCode": "32830"
}
}
}
var uri = "https://MyAzureFunction.azurewebsites.net/api/HttpTriggerPowerShell1?code=MyAuthCode=="
var req = new Request(uri, {
method: 'post',
mode: 'no-cors',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(jsonBody)
});
fetch(req)
.then(function (response) {
console.log(response);
return response.blob();
}).then(function (blob) {
console.log(blob);
});
}
When the function runs I get the following:
Here's what I get from Postman:
What am I doing wrong?
You request the URL in no-cors mode, which is why opaque response is returned. Effectively, that's what you asked for.
Instead, I suggest you configuring CORS for Azure Function as described here and changing mode to cors.

MediaWiki JSON Api always returning "undefined"

I'm trying to retrieve some data from the MediaWiki Api; especifically the registration date of a certain user. Taking Wikipedia as a live example, according to their Api sandbox, the request URL to get the information of Jimmy Wales would be:
/w/api.php?action=query&list=users&format=json&usprop=registration&ususers=Jimbo_Wales
So I make an Ajax call:
$.ajax({
dataType: "jsonp",
url: "/w/api.php?action=query&list=users&format=json&usprop=registration&ususers=Jimbo_Wales",
success: function (data) {
var timestamp = data.query.registration;
console.log(timestamp);
}
});
But if I run that script on Firebug, I simply get "undefined". What am I missing?
The resulting JSON data is something like:
{
"batchcomplete": "",
"query": {
"users": [
{
"userid": 24,
"name": "Jimbo Wales",
"registration": "2001-03-27T20:47:31Z"
}
]
}
}
Of course, data.query.registration is undefined. it is not available. Your have to "address" the user itself. Like data.query.users[0].registration.

AngularJS $http request object for another request

Sorry for the confusing title, basically I have a json file that looks like this that points to other locations:
{
"link": [
{
"href": "some-external-resource",
"title": "services-path"
}
]
}
My real problem is getting the href of the object to not load asynchronously into the Angular service. The following is my request to the above json file:
var servicesPath = $http({
url: 'resource-directory.json',
method: "GET"
}).success(function(data){
return $filter('filter')(data.link, {title: "services-path"})[0].href;
});
console.log(servicesPath);
I know what is being returned is what I want, but the console log returns the standard "then, catch, finally, success, error" object functions, meaning the data isn't there when I need it. How can I manipulate my request so the variable contains the information?
Since you have an async call, the value would be returned when the call is finished (successfully)
$http({
url: 'resource-directory.json',
method: "GET"
}).success(function(data){
console.log('response data', data);
var theHref = $filter('filter')(data.link, {title: "services-path"})[0].href;
console.log('theHref', theHref); // value shows here
}).error(function(errorResp){
console.log('error');
});

Issue: angularjs post data inside then handler

I've got the issue that my $http.post is not working correctly. Everytime I send the post it seems like it doesn't send the data at all.
This is my post:
$http({
method: 'POST',
url: "http://localhost:8080/app/api/v0/user/?access_token=" + UtilService.accessToken,
data: data
}).success(function(data){
console.debug(data);
}).error(function(data){
alert("error");
console.debug(data);
});
The data json:
var data = {
"country": $scope.country,
"firstname": $scope.firstname,
"lastname": $scope.lastname,
"username": $scope.username
}
I get the data from a form in my html.
What I tried so far is to add a header with
headers: {'Content-Type': 'application/json'}
or
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
I also tried JSON.Stringify(data) or angular.toJSson(data) before sending the data.
I even tried the suggestions from Make AngularJS $http service behave like jQuery.ajax()
But nothing seems to work. When I send the post via Postman everything works fine and I get the expected answer. When I send it via $http.post() I just get a empty data as a result and I end up in the error callback.
I am sure that the url I build is correct because of the Postman test. I feel like the issue comes from the data object I send. Even when I send a very simple json like:
{
"firstname": "asdf",
"lastname": "asdf"
}
I still recieve a empty data object.
I searched for hours now and I have no clue where this misbehaviour comes from. I'm very thankful for any advice!
EDIT: It seems like the issue comes from the fact that I'm trying to call the $http.post inside a promise.then(function(result){ /*where I call the $http.post()*/ }).
If I make the call outside the then() I get an appropriate answer. But I need to wait for the data until I can send my post. So what is wrong with the approach of sending a post inside a then()?
EDIT: The hash is the value I need to wait for
var deferred = $q.defer();
createPasswordHash(email, newPassword1,
function (hash) {
deferred.resolve(hash);
},
function (current, total) {
}
);
var promise = deferred.promise;
promise.then(function (result) {
var data = {
"country": $scope.country,
"firstname": $scope.firstname,
"lastname": $scope.lastname,
"username": $scope.username,
"hash": result
}
$http.post("http://localhost:8080/app/api/v0/user/?access_token=" + UtilService.accessToken, data).success(function (data) {
alert("success");
}).error(function (data) {
alert("error");
console.debug(data);
});
});
I had the same problem when i called the $http.post() inside the createPasswordHash method.

Yammer Open Graph Post - How do i do it?

I am trying to figure out how the payload should be constructed for a Open Graph object to submit to yammer. I can post a standard message, but i would like to post an opengraph message instead.
{
"activity":{
"actor":{"name":"Sidd Singh",
"email":"sidd#xyz.com"},
"action":"create",
"object": {
"url":"https://www.sched.do",
"title":"Lunch Meeting"
},
"message":"Hey, let’s get sushi!",
"users":[
{"name":"Adarsh Pandit",
"email":"adarsh#xyz.com"}
]
}
}
This is some code nicked from their API documentation but doesn't show me how i should use this in javascript. Can someone assist me? Below is my existing code that posts a standard message...
yam.request({
url: "https://www.yammer.com/api/v1/messages.json?network_id=networkname", //this is one of many REST endpoints that are available
method: "POST",
beforeSend: function (req) { //send the access_token in the HTTP header
req.headers.Authorization = "Bearer " + access_token;
},
data: {
"network": "networkname",
"body": "Test Post",
"group_id": "3719771"
},
success: function (data) { //print message response information to the console
toastr.success('An Item was successfully posted to Yammer', "Yammer Network");
},
error: function (user) {
toastr.error('There was an error eith the request', "Yammer Network");
}
});
This post answered your question: Yammer Open Graph API Error 400
Simply replace the key value pairs in the data{} with the activity json strings. Also remember to change the RESTful api endpoint to https://api.yammer.com/api/v1/activity.json

Categories