Angular $http jsonp: how to parse through data - ajax

I'm starting to learn Angular and I want to play around with the $http call function.
I basically want to make a get request to an external API:
angular.module('pokedexApp')
.controller('MainCtrl', function ($scope, $http) {
var response;
$http.jsonp("http://pokeapi.co/api/v1/pokemon/1/").success(function(response) {
response = response;
})
$scope.pokemon = response;
});
I'm probably completely wrong as to how this works. I basically want to {{ pokemon }} out a response to test it.
I'm getting a Uncaught SyntaxError: Unexpected token : error and I can't tell if it's because the return data isn't properly formatted or what.

The error is because in angular it will try to parse this response in json type. And it failed to parse, so it throw an error:
Uncaught SyntaxError: Unexpected token :
Seems in angularjs you'd better to handler jsonp response by your self.
$scope.triggerJsonp = function(){
$http.jsonp("http://pokeapi.co/api/v1/pokemon/1/", {params: {'callback':'eqfeed_callback'}});
};
window.eqfeed_callback = function(data){
$scope.response = data;
}
Here is jsfiddle.
Relative issue in jquery.ajax JSONP call showing "Uncaught SyntaxError: Unexpected token : " And answer use own callback to handle this.

It doesn't look like the website provides JSONP support - https://github.com/phalt/pokeapi_issues/issues/30
Your $http request is fine but you currently have a scoping issue with respect to 'response'. This is how your code should be written in order for your scope variable to be defined correctly:
angular.module('pokedexApp')
.controller('MainCtrl', function ($scope, $http) {
$http.jsonp("http://pokeapi.co/api/v1/pokemon/1/").success(function(response) {
$scope.pokemon = response;
})
});

Related

How do I get a specific column name values using Axios Promise-based Http Request in Vue.js and Laravel 8

If I do this in my Vue.js script component
getResumeAPIData(id){
// declare a response interceptor
axios.interceptors.response.use((response) => {
// do something with the response data
console.log('Response was received');
return response;
}, error => {
// handle the response error
return Promise.reject(error);
});
// sent a GET request
axios.get(`api/resume-data-returns/${id}`)
.then((response)=>{
this.RelationTable = response.data
console.log(this.RelationTable);
})
},
I get a response like this
{"id":1,"name":"userlocalvm","email":"userlocalvm#v","email_verified_at":null,"type":"user","bio":"Why","photo":"1606931001.jpeg","created_at":"2020-12-02T16:01:00.000000Z","updated_at":"2020-12-02T17:43:21.000000Z"}
Because of my Laravel api.php->Controller Backend code
$findOrFailId = Resumes::findOrFail($forEachId);
$foreignKeyOfResTable = $findOrFailId->user_id;
return User::findOrFail($foreignKeyOfResTable);
But if I do it like this as
// sent a GET request
axios.get(`api/resume-data-returns/${id}`)
.then((response)=>{
this.RelationTable = response.data.created_at
console.log(this.RelationTable);
})
The added dot then the property name of the column
response.data.created_at
I get a response
undefined
Sorry if this is a silly question as I am still quite a rookie in programming in general and the jargons that comes with it and I want learn and master javascript and php so bad!
It might be that the response is inside another data object. You might have to do something like this:
response.data.data.created_at

Vue error for pagination: response is not defined

I keep getting this Vue error: "ReferenceError: response is not defined" but when I check in the console, the data is all there.
I intend to use the data from the response to make pagination. Thanks in advance.
Methods
getAllUserData(){
let $this=this;
axios.get('api/members/getAllMembersData').then(response=>this.members=response.data.data);
$this.makePagination(response.meta,response.links);
},
makePagination(meta,links){
let pagination={
current_page:meta.current_page,
last_page:meta.last_page,
next_page_url:links.next,
prev_page_url:links.prev
}
this.pagination = pagination;
}
axios.get() is an async function. The code that follows this function will not be executed after the ajax request completes, but long before that. Because of this, the variable response does not exist yet.
All code that has to be executed when the ajax call completes has to be put in the .then() function of the call.
getAllUserData(){
axios.get('api/members/getAllMembersData').then(response => {
this.members = response.data.data;
this.makePagination(response.data.meta, response.data.links);
});
},
Your response is still inside the axios get method, therefore the makePagination function has to be called inside axios method as well (inside .then())
getAllUserData(){
let $this=this;
axios.get('api/members/getAllMembersData').then(response=>
this.members=response.data.data
$this.makePagination(response.data.meta,response.data.links);
},
makePagination(meta,links){
let pagination={
current_page:meta.current_page,
last_page:meta.last_page,
next_page_url:links.next,
prev_page_url:links.prev
}
this.pagination = pagination;
}

Angular Js - Test POST request that returns an object with Jasmine

I have a service set up which makes all my AJAX calls. I want to test my login method, which sends an AJAX POST $http.post to a particular URL, which returns an objects with the result (login passed or failed). This result is an object. I have not return the code exactly to test the service, but I'm trying to test the URL first. This is how it looks right now:
'use strict';
describe('Service: Ajax', function () {
var service, httpBackend;
// load the service's module
beforeEach(module('mySampleApp'));
// instantiate service
beforeEach(inject(function (Ajax, _$httpBackend_) {
httpBackend = _$httpBackend_;
service = Ajax;
}));
it('Test AJAX call', function () {
httpBackend.expect('POST', 'http://myloginurl', {u: 'xyz', p: 'pass'}, { withCredentials: true})
.respond(201, 'success');
});
});
This passes. Now I tried putting a wrong URL, wrong username/password, but it still passes! How do I test this?
UPDATE:
Better written now:
//Ajax is my AJAX service
it('should test the login AJAX call', inject(function (Ajax) {
httpBackend.expect('POST', 'http://myloginurl')
.respond(200, "[{ status: 200, //some more data }]");
httpBackend.flush();
Ajax.authenticate({u: 'xyz', password: 'pass' })
.then(function(data){
expect(data.status).toBe(200);
});
}));
I get this:
PhantomJS 1.9.7 (Linux) Service: Ajax should test the login AJAX call FAILED
Error: No pending request to flush !
blah blah...
You need to put a
httpBackend.flush();
in that will throw an exception if the expected url wasn't called - thereby failing your test.
Also, I can't see that you're calling the code that does the Ajax request anywhere - you need to do that before calling flush().
So something like:
it('Test AJAX call', function () {
httpBackend.expect('POST', 'http://myloginurl', {u: 'xyz', p: 'pass'}, { withCredentials: true})
.respond(201, 'success');
service.functionThatMakesCallToServer();
httpBackend.flush();
});
If functionThatMakesCallToServer() calls the url in the httpBackend.expect(...) line, everything will be ok. If it doesn't httpBackend.flush() will throw an error as a call that was expected did not happen. The error will cause your test to fail.

Brightcove Media API Access-Control-Allow-Origin

I'm attempting to call the Media API but am getting an Access-Control-Allow-Origin error.
I tried appending '?jsoncallback=?' to my url (JSONP) and it now returns the JSON file but my browser is trying to interpret it as javascript and throwing an error.
(function() {
var mediaAPI = "http://api.brightcove.com/services/library?jsoncallback=?";
$.getJSON( mediaAPI, {
command: "find_video_by_id",
video_id: "2472866007001",
video_fields: "videoStillURL,thumbnailURL",
media_delivery: "http",
token: "4kDMVfqenhDk_uU2MvV8fioVrHsHwiKWCLFuxZumIq7fSa3wyRkTNw..",
format: "json"
})
.done(function( data ) {
var obj = jQuery.parseJSON(data);
alert( obj.name === "videoStillURL" );
});
})();
If you use callback instead of jsoncallback the Media API will return a JSONP response (JSON wrapped in a callback function)
You shouldn't use jQuery.parseJSON() with that type of response, alert(obj.videoStillURL) will work.
Change format: "json" to format: "jsonp"... should fix it for you

Getting global handler to all AJAX calls in dojo

I need to invoke some common methods before an AJAX call is made and after the AJAX call (before the actual handler method is called) is success. I'm using dojo.aspect to achieve this.
This is my code sample
function makeAjaxCall(){
dojo.xhrGet({
url:"sample_url",
content:{
test:"value"
},
load:function(response){
//Do some logic here
},
error:function(response){
//handle error
}
});
}
Below is the dojo.aspect which I'm using to get a hook to the XHR calls.
define(["dojo/aspect"], function(aspect){
aspect.after(dojo, "xhr", function(deferred){
console.log("AJAX AFTER");
deferred.then(function(response){
//CALLED AFTER 'load' METHOD IS CALLED.
console.log("Testing");
});
});
aspect.before(dojo, "xhr", function(method, args){
console.log("AJAX BEFORE");
});
});
Now the problem is deferred.then inside aspect.after is called after the "load" function is called. Is it possible to have a method which is called before the actual load method is invoked?
The short answer is yes.
First, there are two ways to make ajax calls in Dojo.
dojo/xhr - this is what you have above and this is deprecated
in favor of
dojo/request/xhr
The first implementation will call into the second implementation. So I would recommend using aop on dojo/request/xhr.
aspect.around(require.modules['dojo/request/xhr'], 'result', function(originalXhr){
return function(url, options, returnDeferred){
var dfd = new Deferred();
// Logic before making the xhr call
originalXhr(url, options, returnDeferred)
.then(function(response) {
// Logic handling the response but before resolving the deferred.
dfd.resolve(vm);
// Logic after resolving the deferred.
}, function(err){
// error handling?
dfd.reject(msgs);
}, function(update) {
dfd.progress(update);
});
return dfd;
};
});
You can find the complete implementation at
https://github.com/cswing/evinceframework/blob/master/evf-web-js/src/dojo/evf/serviceRegistry.js (~ line 111)
USAGE:
require('dojo/xhr/request', function(xhr){
xhr({...}).then(
function(response) {
//handle response
},
function(error) {
//handle error
}
);
});
The dojo/xhr code will translate itself to the usage above, so the code you posted should work.
If you switch to the new API - dojo/request
Then you could use dojo/request/xhr and dojo/request/notify
In Dojo 1.10 there is new API to globally catch state of requests.
notify("error", function(error){
console.error(error);
//SyntaxError: Unexpected token < in JSON at position 0(…)
});
But in my case I get errors in html eg. so in error I get "error SyntaxError: Unexpected token < in JSON at position 0(…)"
In previous version there was an access to response object:
topic.subscribe("/dojo/io/error", function(/*dojo.Deferred*/ dfd, /*Object*/ response){
if (response.status === 401) {
window.location.reload();
}
});
So I figured out that json handler can be customized:
require(["dojo/request/handlers"], function(handlers){
handlers.register("json", function(response){
if (response.status === 401) {
window.location.reload();
return;
}
return JSON.parse(response.text || null);
});
});
This way you are able to detect response.errors before JSON.parse throws exception.

Resources