angular js jsonp example dosn't works - angularjs

im having trouble using the angular js jsonp function, i cant make this plunk to work:
http://plunker.co/edit/xQVBchTYOro1CB979021
can anyone help me?

With the JSONP "hack" you must make sure that the server's response contains callback's invocation. To make your example work you should change the prov.json file so it looks like follows:
angular.callbacks._0({
"id": "40796308305",
"about": "The Coca-Cola Facebook Page is a collection of your stories showing how people from around the world have helped make Coke into what it is today.",
...
})
There are many sources on JSONP, ex.: What is JSONP all about?

using a get instead of jsonp, you get the details of cokacola...
async: function(page) {
var url = 'prov.json';
var promise = $http.get(url).error(function (response, status) {
alert("fai");
}).success(function (response, status) {
alert(response.about);
}).then(function (response, status) {
return response.data;
});
return promise;
}};

Related

angularjs PATCH method 404 response

WORK AROUND IS AT THE BOTTOM
Original problem
There are question like this all over the web and none of them really have answer for me. I can't get an http PATCH operation to work using angular to save my life. I've implemented $http, with shortcut $http.patch and without using the config object method:PATCH. I've used $resource by adding a custom method. And I've implemented Restangular using their patch and I'm getting the same error. I have the correct Content-Type as suggested in other posts. I think it's safe to say at this point, it's something I'm missing. I'm getting the same "404" message via postman when trying to patch. I can PUT, GET, POST, and DELETE, but not PATCH.
In the following images you can see that the resource exists for GET. But when trying to patch I get 404. Browsing to that endpoint shows the record. Which is stored in Mongodb.
Here's some code snippets:
Resangular GET:
var corporiumRecord = Restangular.one('corporium-mgmnts', $scope.uuid);
corporiumRecord.get().then(function(res) {
console.log(res)
}, function(err) {
console.log('Restangular failed: ', err)
});
Restangular Patch:
var data = {
corporiumId: $scope.newBlock
};
var corporiumRecord = Restangular.one('corporium-mgmnts', $scope.uuid);
corporiumRecord.patch(data).then(function(res) {
console.log(res)
}, function(err) {
console.log('Restangular failed: ', err)
});
$http attempt using config object:
controller code:
httpCorporiumSrv.updateCorporiumId('/corporium-mgmnts/' + $scope.params.id, data)
.then(handleUpdateSuccess)
.catch(handleUpdateError);
service code, tried forcing the content-type header but got same result
with or without it:
function updateCorporiumId(url, data) {
return $http({
method: 'PATCH',
url: url,
data: angular.toJson(data),
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
//transformRequest: transformUpdateData
})
.then(handleUpdateSuccess)
.catch(handleUpdateErrors);
}
Using the .patch shortcut:
function updateCorporiumId(url, data) {
return $http.patch(url, data, {
transformRequest: transformUpdateData
})
.then(handleUpdateSuccess)
.catch(handleUpdateErrors);
}
Thing is I've tried this every which way I know how. I don't even know how to start debugging any more. I'm just getting 404 on a resource that does exist. Any suggestions on what might be happening to my request would be great.
Resolution:
For anyone having this issue, if you could post the fix or what's going on here to this point or PM me that would be awesome I'd like to know. I ended up just using PUT to fix this.
Quick Restangular solution:
Build the url template for findByOne like function using Restangular.one(url, _id) where '_id', is the id of the resource you're looking for. .get() goes out and finds that one resource by said id, which you can populate dynamically however you like. Once you have the one resource with GET copy it with Restangular.copy() which is different from angular.copy as it doesn't bind 'this' to the new object. Change what needs to be changed or added in the new object and then perform a .put() on it.
var corporiumRecord = Restangular.one('corporium-mgmnts', $scope.uuid);
corporiumRecord.get().then(function(res) {
var update = Restangular.copy(res);
// update date corporiumId
update.corporiumId = $scope.newBlock;
// submit new doc with altered value
update.put().then(function() {
console.log('updated')
});
console.log(update)
}, function(err) {
console.log('Restangular failed: ', err)
});
Also because mongo uses _id and Restangular uses id you have to add this to your module
angular.module('corporium-mgmnts').config(function(RestangularProvider) {
RestangularProvider.setMethodOverriders(['put', 'patch']);
// setRestangularFields is required for mongodb
RestangularProvider.setRestangularFields({
id: "_id"
});
});

Can't get only the header in AngularJS (v1.3.15) using $resource and method 'HEAD'

In Angular (v1.2.19), I was able to do something like this in a factory :
myApp.factory('GetNumber', ['$resource',
function($resource) {
var get_headers = $resource('some/url', null, {
get_number: {
method: 'HEAD',
transformResponse: function(data, headers) {
var count = headers()['x-number'];
return count;
}
}
});
return get_headers;
}
]);
Call it from my controller like this:
$q.all({
'item1': GetNumber.get_number().$promise,
'item2': SomeOtherService.get().$promise
})
.then(function(results) {
$scope.newNumber = results.item1.value;
});
And I could get the custom header back without having to retrieve the whole header.
Now in v1.3.15, it doesn't work. I can see the header in Chrome with 'x-number' in the header, but if I put a breakpoint in Chrome on the 'var count' line, I never hit it (and I do hit it with v1.2.19).
I've verified that using $http.head works, so if I have this in my controller:
$http.head('some/url')
.success(function(data, status, headers, config) {
var count = headers()['x-number'];
$scope.newNumber = count ? count : 0;
});
I get my scoped value.
I've noticed that there aren't a whole lot of examples of people using the http 'HEAD' method and I'm wondering if there's a reason that I haven't located yet through searching?
I did find this StackOverflow question and answer HTTP Get: Only download the header? (HEAD is not supported) and while I agree with the statement, I don't want the overhead of requesting the headers and the body.
Any suggestions please?
Julie
Thank you to Kevin for suggesting that I use an error handler. I should've thought to try that myself, but I didn't.
Anyway, that lead me to the answer to my problem. To try and catch an error in $resource, it's suggested you use interceptors. I've never used them before and I utilized AngularJS documentation (https://docs.angularjs.org/api/ng/service/$http#interceptors) and changed the code in my factory to be:
myApp.factory('GetNumber', ['$resource',
function($resource) {
var get_headers = $resource('some/url', null, {
get_number: {
method: 'HEAD',
interceptor: { response: function(response) {
var count = response.headers()['x-number']:
return count ? count : 0;
}, responseError: function(rejection) {
console.log('rejection: ', rejection);
}}
}
});
return get_headers;
}
]);
I'm still not sure why transformResponse stopped working and I now need to use interceptor, but very happy I don't have to request the whole body now!
Julie

AngularJS jsfiddle $http echo not returning data

I encountered a bug in a square-connect API wrapper for node, and I made a fiddle to recreate the issue. I noticed my code wasn't working, in the sense that angular {{}} stuff isn't showing up. What's wrong with it?
the only thing I'm trying to do is have the raw JSON object (preferably {{res}}, but it doesn't matter really) shown below the create button. I am just trying to demonstrate to the author of a library that my object and data is valid, and that a bug is in his library, not my implementation.
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: item
}).success(function(data, status) {
$scope.res = data;
}).failure(function(data, status){
$scope.res = data+status;
});
data is not being returned from jsfiddle's ECHO.
http://jsfiddle.net/efjytg6r/2/
You were close, but since you're saving your $http in a variable, you access the methods within it using that variable. (ie: httpRequest.success / etc)
Also it's .error() not .failure()
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: item
});
httpRequest.success(function(data, status) {
$scope.res = data;
});
httpRequest.error(function(data, status){
$scope.res = data+status;
});
jsFiddle is finicy with it's echo AJAX examples. You need to format what you send to them correctly with json, have it stringified as well as use jQuery's $.param (since angular doesn't do POST like you're used to with jQuery).
I included jQuery to the fiddle below.
I formatted the data being sent differently
I moved your {{ res }} inside of the controller area (you had it outside, which means it won't compute)
I added | json filter to {{ res | json }}
Updated jsFiddle
// the wacky format you need if you want to do fake $http to jsFiddle
// case in point, if you're trying to DEMO this, I wouldn't even bother, since it won't look like this when you actually use this within your application
var data = $.param({
json: JSON.stringify({
item
})
});
$http.post("/echo/json/", data)
.success(function(data, status) {
$scope.res = data;
}).error(function (status) {
});
Here is an example using $httpParamSerializer and a delay.
angular.module('myApp',[]);
angular.module('myApp').controller('myVm',
function($scope,$http,$httpParamSerializer) {
var vm = $scope;
var xitem = {a:"1",b:"2"};
var data = $httpParamSerializer({
json: xitem,
delay: 6
});
console.log("Posting xitem");
vm.p = $http.post('/echo/json/',data);
vm.p.then (function(response) {
console.log(response);
console.log(response.data)
})
});

angular-http-auth with $http transformResponse

I'm using angular-http-auth to show a login dialog whenever a 401 "unauthorized" response is returned from the server.
Since I'm cool, I also try to deserialize response objects in my services. For example, if a service requests a car and the response is {make: Honda, model: Civic}, I try to deserialize that into a Car object using transformResponse.
For example:
getCar: function() {
return $http.get('/api/car', {
method: 'GET',
transformResponse: function(data, headers) {
var c = angular.fromJson(data);
return new Car(c);
}
});
}
This doesn't work with angular-http-auth. If the response was a 401 Unauthorized, you'll get a javascript error. It's because angular will try to run that transformResponse code even if the response was a 401.
It turns out that $http interceptors (which is what angular-http-auth uses) are run AFTER the transformResponse code. That's a huge problem, because none of that code in transformResponse will work if the server response was a 401 (there wouldn't be any data)
Is this a problem for anyone else? How did you get around it? Am I not to use transformResponse if I use $http interceptors?
Late to the party, I know, but to anyone coming here from Google like I did (I also posted this as a comment on a related issue filed with the Angular repo):
I also found it to be confusing that response interceptors run after the transformResponse method. I added a method to $http.defaults.transformResponse. Here is an example from the documentation on how to do that.
So, if you need to basically have a response interceptor that runs before the transformResponse method, this should do it:
'use strict';
angular.module('app')
.run(function ($http) {
$http.defaults.transformResponse.push(function (data, headers) {
// do stuff here before the response transformation
// Be sure to return `data` so that the next function in the queue can use it.
// Your services won't load otherwise!
return data;
});
});
If your services or http calls don't have their own response transformer, you're good now.
If your services do have their own transformResponse method, they will actually override all default transformers (I found this out after a long read of the documentation), and the above code will not run.
To circumvent this, you can follow this example in the docs.
To get around this problem I don't use transformResponse anymore. I just can't see the point of transformResponse if it runs before $http interceptors.
In order to use angular-http-auth and also deserialize responses in your services, you can write your services so that they execute the HTTP request first and then deserialize the response in a callback function.
As an example, here is how I would have restructured the example in the OP:
Plunker
services.factory('HttpCarService', function($resource, $q) {
var resource = $resource('/api/car');
return {
getCar: function() {
var deferred = $q.defer();
var car = null;
var successCallback = function(data, status, headers, config) {
var c = angular.fromJson(data);
car = new Car(c);
deferred.resolve(car);
};
var errorCallback = function(data, status, headers, config) {
deferred.reject("something wrong");
};
var result = resource.get(successCallback, errorCallback);
return deferred.promise;
}
};
});
This pattern will also work if data is an array.
$http interceptors will run before either of the callback methods are executed. If your $resource needs url params, you can make the getCar() function accept a config object as a parameter, and pass the necessary information on when you make the $resource.get() call.

angular.js and untappd API, how to send a Get request

I'm trying to connect to Untappd API trought angular.js; the API docs says
Whenever you are making a call to the API, you MUST pass both your Client ID and Client Secret as GET params like below
http://api.untappd.com/v4/method_name?client_id=CLIENTID&client_secret=CLIENTSECRET
with angular I have done this simply controller
function UntappdController($scope,$http) {
$http.get('http://api.untappd.com/v4/user/badges/jonnyjava?client_id=XXX&client_secret=XXX').success(function(data) {
alert('ok');
}).
error(function(data, status, headers, config) {
alert('ko');
});
}
UntappdController.$inject = ['$scope', '$http'];
but it doesn't work. (I get always KO)
So I'have tried tro a RESTful service. In this way
angular.module('BadgeServices', ['ngResource']).
factory('Badge', function($resource){
return $resource('http://api.untappd.com/v4/user/badges/jonnyjava/', {}, {
query: {method:'GET',params:{client_id: 'XXX', client_secret: 'XXX'}, isArray:true}
});
});
But this doesn't works too...
What I'm doing wrong? I'm new to angular. It looks simple but I'm missing something fundamental...
The error function is passed these variables: data, status, headers, config. Check their contents - I'm sure the server has some why of specifying what went wrong.
Sorry, I forgot it! Here is what I get with the error function..
data: status:0 headers:function (name) {
"use strict";
if (!headersObj) headersObj = parseHeaders(headers);
if (name) {
return headersObj[lowercase(name)] || null;
}
return headersObj;
}config:[object Object]
Nothing helpful...
Solved! It was a CORS problem. If anyone is interest the solutions is here.
stackoverflow-Angularjs issue $http.get not working

Resources