How can I replicate this ajax call using an Angular $resource? - javascript

I am attempting to make calls to the Mockaroo API.
This example they use in the docs works when I make the same call from my angular app (this probably goes without saying - but I did replace the api key here with my own api key - the same is true for the attempts below as well)
Working Example (using $.ajax)
var fields = [{
name: "yearsEmployed",
type: "Number",
min: 1,
max: 30,
decimals: 0
}, {
name: "department",
type: "Custom List",
values: ["R+D", "Marketing", "HR"]
}, {
name: "dob",
type: "Date",
min: "1/1/1950",
max: "1/1/2000",
format: "%m/%d/%Y"
}];
var url = 'http://www.mockaroo.com/api/generate.json?key=abcd1234' +
'&fields=' + encodeURIComponent(JSON.stringify(fields));
$.ajax(url, {
dataType: 'jsonp',
contentType: 'application/json',
success: function(data) {
console.log('yearsEmployed', data.yearsEmployed);
console.log('department', data.department);
console.log('dob', data.dob);
}
});
However, I would like to use an angular $resource, but when I try replacing the $.ajax portion of the example above using any of these methods, I get errors. What is the correct method to accomplish this?.
Attempt #1
// using fields variable from above example
var url = 'http://www.mockaroo.com/api/generate.json?key=:key' +
'&fields=:fields';
var params = {
key: 'abcd1234',
fields: fields
}
return $resource(url, params, {
all: {method:'JSONP', isArray: false }
});
Attempt #1 error:
GET http://www.mockaroo.com/api/generate.json?key=abcd1234&fields=%5Bobject%20Object%5D,%5Bobject%20Object%5D,%5Bobject%20Object%5D
Attempt #2
// using fields variable from above example
var url = 'http://www.mockaroo.com/api/generate.json?key=:key' +
'&fields=:fields';
var params = {
key: 'abcd1234',
fields: fields
}
return $resource(url, params, {
all: {method:'POST', isArray: false }
});
Attempt #2 error:
XMLHttpRequest cannot load http://www.mockaroo.com/api/generate.json?key=abcd1234&fields=%5Bobject%20Object%5D,%5Bobject%20Object%5D,%5Bobject%20Object%5D. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 400.
Attempt #3:
// using fields AND url variables from example above
return $resource(url, {}, {
all: {method:'POST', isArray: false }
});
Attempt #3 error
XMLHttpRequest cannot load http://www.mockaroo.com/api/generate.json?key=abcd1234&fields=%5B%7B%22name…ax%22%3A%221%2F1%2F2000%22%2C%22format%22%3A%22%25m%2F%25d%2F%25Y%22%7D%5D. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
Attempt #4:
// using fields AND url variables from example above
return $resource(url, {}, {
all: {method:'JSONP', isArray: false }
});
Attempt #4 error:
Refused to execute script from 'http://www.mockaroo.com/api/generate.json?key=abc31234&fields=%5B%7B%22name…ax%22%3A%221%2F1%2F2000%22%2C%22format%22%3A%22%25m%2F%25d%2F%25Y%22%7D%5D' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.
Edit #1
Updated Attempt #1
var params = {
key: 'abcd1234',
fields: JSON.stringify(fields)
}
Updated Attempt #1 Error:
Refused to execute script from 'http://www.mockaroo.com/api/generate.json?key=abcd1234&fields=%5B%7B%22name…2,%22max%22:%221%2F1%2F2000%22,%22format%22:%22%25m%2F%25d%2F%25Y%22%7D%5D' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.

Related

Error sending Content_Tags while posting a video using FB API

I have tried many different ways but to no avail
API Spec - https://developers.facebook.com/docs/graph-api/reference/page/videos/
Param - content_tags ( list ) --> is what required
Below is my form data that is being posted
const formData = {
file_url: postOptions.filepath,
title: postOptions.title,
description: postOptions.description,
content_tags: ['tags', 'hello', 'hi']
};
HTTP Request Options
const options = {
url: https://graph-video.facebook.com/v9.0/${pageId}/videos?access_token=${accessToken},
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
},
formData,
};
Error response returned.
{"error":
{
"message":"(#100) Param content_tags[0] must be a valid ID string (e.g., \"123\")",
"type":"OAuthException",
"code":100,
"fbtrace_id":"ANoCbTSnh4uL960SjyE6XBV"
}
}
As per documentation, seems it has to be not just any string but NUMBER string which are predefined IDs of the tag list<numeric string>
From documentation
Tags that describe the contents of the video. Use search endpoint with type=adinterest to get possible IDs.
Example:
~~~~
/search?type=adinterest&q=couscous
~~~~
Here's full path of the above example shown by facebook, how you can get some IDs:
https://graph.facebook.com/search?type=adinterest&q=​"home"&limit =10&access_token={{access_token}}

Error sending AJAX POST request from local .html file to localhost:8080. CORS: "It does not have HTTP ok status."

I am getting an error when attempting to send a POST via AJAX from my own .html and .js files to localhost:8080. Upon submitting the request, the full error reads: "Access to XMLHttpRequest at 'http://localhost:8080/contact/new-message' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
CORS is already enabled on my browser, so access is automatically "Access-Control-Allow-Origin : *", so this is a different from that error.
Is there a way to include an "ok" status in the header? Or is the problem arising from elsewhere? Any help is greatly appreciated. Here are some code snippets:
My JavaScript, which runs as part of a form-submission:
function submitMessageAJAXCall(inputName, inputEmail, inputMessage, inputRegion) {
$.ajax({
type: 'POST',
url: 'http://localhost:8080/contact/new-message',
data: JSON.stringify({
rbName: inputName,
rbEmail: inputEmail,
rbMessageText: inputMessage,
rbRegionId: inputRegion
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
success: function() {
alert('Success!');
displayThankYouMessage();
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Unfortunately that message did not go through.');
}
});
}
The Java code which recieves it:
#PostMapping("/new-message")
private ResponseEntity<HttpStatus> addNewMessage(#RequestBody RBNewMessage rbNewMessage) {
//validate message in service layer
boolean isRequestValid = contactService.validateNewMessageRB(rbNewMessage);
//is message is good, save it; else, return an error
if (isRequestValid == true) {
//create a new message
ContactMessage message = new ContactMessage();
//set message fields
message.setMyName(rbNewMessage.getRbName());
message.setMyEmail(rbNewMessage.getRbEmail());
message.setMessageText(rbNewMessage.getRbMessageText());
LocalDateTime timeOfMessage = LocalDateTime.now();
LocalDateTime timeWithoutNano = timeOfMessage.withNano(0);
message.setTimeStamp(timeWithoutNano);
int regionId = rbNewMessage.getRbRegionId();
Region region = regionService.getRegionById(regionId);
message.setRegion(region);
ContactStatus cs = contactStatService.getStatusById(1);
message.setContactStatus(cs);
//save message
contactService.save(message);
//return success
return new ResponseEntity<>(HttpStatus.OK);
} else {
//return error
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
And this is an example of a Postman request that is successful:
{
"rbName": "John Johnson",
"rbEmail" : "JohnJohnson#Email.com",
"rbMessageText" : "Hello there, this is my message.",
"rbRegionId" : 5
}
Add #CrossOrigin annotation (import org.springframework.web.bind.annotation.CrossOrigin) to the top of the controller class that is handling the request.

How to use an API with an app Fiori (SAPUI5)

I am trying to use this Mercedes Benz API in my app. Inside controller I have a ajax request:
onInit : function () {
var oModel = new JSONModel();
var url = 'https://api.mercedes-benz.com/image/v1/vehicles/WDDZH3HB8JA394212/components?apikey=my_apikey';
$.ajax({
beforeSend: function() {
//armamos la url y la asignamos a una var
},
url: url,
type: 'GET',
accepts: "application/json",
success: function (resp) {
console.log(resp)
},
error: function (jqXHR, estado, error) {
console.log(error +":" + " " + estado)
},
timeout: 10000
});
},
I just want response as OK but getting some error:
Request header field X-XHR-Logon is not allowed by
Access-Control-Allow-Headers in preflight response.
Responses
If you take a look to the documentation API I just need the API key. Maybe I am doing something wrong? Guide me if you has use an API inside a FIORI app it will be thankful
NOTE: my fiori server is on premise so we don't use SCP
If you really want to do an XHR you need to whitelist APIKEY in neo-app.json like this
{
"welcomeFile": "/webapp/index.html",
"routes": [{
...
],
"sendWelcomeFileRedirect": true,
"headerWhiteList": [
"APIKey"
]
}
Otherwise I strictly recommend using destinations, explained in here:
SAPUI5 / AJAX, submitting Basic Authentication Details (solved)
Authentication API in SAPUI5 without SAP Cloud Platform and Destinations (not solved)

HTTP params entries sharing the same key

This Meteor server code uses HTTP 1.1.7 to make a POST request to match what I did using java but I can not figure out how to include more than one entry into the request params which have the same key.
//in java 'working'
HttpParams javaParams = new HttpParams();
javaParams.add('food','milk')
javaParams.add('food', 'water')
javaParams.add('food', 'ice')
javaParams.encodeParameters("UTF-8");
//in javascript 'not working'
let headerObject {
"Content-Type" : "application/x-www-form-urlencoded",
'Accept-Language': 'en-US,en;q=0.5'
and others
}
const response = HTTP.call('POST', myUrl, {
timeout: 30000,
headers: headerObject,
params: {
'food': 'milk',
'food': 'water',
'food': 'ice'
}
});
//also tried these but server returned status code 500
food: ['milk', 'water', 'ice']
'food[]': ['milk', 'water', 'ice']
How can it this be done? Thanks
In JavaScript, just use an array:
const response = HTTP.call('POST', myUrl, {
timeout: 30000,
headers: headerObject,
params: {
food: ['milk', 'water', 'ice']
}
});
However, different languages on the server side use different mechanisms to handle parameter arrays. While Java should work with the above code, PHP for example needs the parameter name to contain square brackets, so the call would need to be
const response = HTTP.call('POST', myUrl, {
timeout: 30000,
headers: headerObject,
params: {
'food[]': ['milk', 'water', 'ice']
}
});
In the current case, the server side seems to expect each entry in a separate line of the request content as key=value pairs which each key being 'food'. Regrettably, this cannot be done with an JavaScript array nor with a JavaScript object.
To circumvent this problem, we use data instead of params. This prevents HTTP.call() from creating data from the given params. It only requires us to handle concatenation of the parameters ourself:
const response = HTTP.call('POST', myUrl, {
timeout: 30000,
headers: headerObject,
data: "food=milk\nfood=water\nfood=ice"
});

ExtJS GET action to store returns 500 in FireFox

I'm getting the strangest behavior from FireFox when loading data from a Web API GET request whereas other browsers do this perfectly. Here is what Fiddler can tell me when I use Firefox:
3817 500 HTTP localhost:52543 /api/Tasks/Get?_dc=1442848131483&page=1&start=0&limit=25 5 403 private application/xml; charset=utf-8 firefox:138020
Same action, other browser (Chrome):
3954 200 HTTP localhost:52543 /api/Tasks/Get?_dc=1442848159073&page=1&start=0&limit=25 1 508 no-cache; Expires: -1 application/json; charset=utf-8 chrome:2808
I'm unable to catch the error in the Application_Error, nor do I receive errors in the exception listener on the client-side, so I suspect something is going wrong between returning the result to the client and the client processing the results, but I have no clue at all where the problem might be situated.
Here is the store definition:
Ext.define('SchedulerApp.store.UnplannedTaskStore', {
extend: 'Ext.data.Store',
model: 'UnplannedTask',
autosync: false,
autoLoad: true,
proxy: {
type: 'rest',
api: {
read: '/api/Tasks/Get',
add: '/api/Tasks/Add',
update: '/api/Tasks/Update',
destroy: '/api/Tasks/Destroy'
},
actionMethods: {
create: 'POST',
read: 'GET',
update: 'POST',
destroy: 'POST'
},
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'total'
},
writer: {
type: 'json',
writeAllFields: true
}
},
listeners: {
load: function (sender, node, records) {
},
exception: function (proxy, response, options) {
Ext.MessageBox.alert('Error', response.status + ": " + response.statusText);
}
}
});
and the model:
Ext.define('UnplannedTask', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Importance', type: 'float' },
{ name: 'Category', type: 'string' },
{ name: 'TaskNo', type: 'float' }
]
});
This is what I have in the Web API:
[System.Web.Http.HttpGet]
public async Task<dynamic> Get(string page, string start, string limit)
{
// Get items from database with request information from the Kendo Grid Control
PagingResult<TaskViewModel> tasks = await this.Worker.GetPagedTasksAsync(int.Parse(page), int.Parse(limit), null, null);
// Map them to store objects
var convertedTasks = new SchedulerTasksViewModel()
{
total = tasks.Count,
data = tasks.Items.Select(x => new SchedulerTask()
{
Importance = x.Importance,
Category = x.Category,
TaskNo = x.TaskNumber
}).ToArray()
};
var response = Request.CreateResponse(HttpStatusCode.OK, convertedTasks);
return response;
}
Could it be a browser issue or am I missing something on the server side?
Try adding this header to your proxy:
headers: {'Content-Type': "application/json" }
I would like to elaborate a bit. The error is thrown by the XML serializer; you don't see the details because IIS does not send them to the front.
I would recommend to modify all your API calls such that they work with XML as well - even if your front-end does not use XML. It's far easier to debug if you can just open API calls in new browser tabs and the XML serializer does not mask code errors with serialization errors.
To see the error message, you would have to allow your development IIS to bring errors to the front:
Open the IIS7 manager
Select the Website and on its features view, double click on “Error Pages”.
Right click and select the “Edit Feature Settings…” or select the same from the Actions pane (in the right hand side)
Select the “Detailed errors” radio button and click on OK
(Source)
My best guess is that you just have to decorate some types or properties with [DataContract], [DataContractAttribute] or [DataMemberAttribute]. The error message will tell you which ones and how to decorate.
Another thing entirely: If you use more than one Ajax request, I'd recommend to define an override on the Ajax proxy. That way you can't forget one:
Ext.define("MyApp.override.Ajax", {
override:'Ext.data.proxy.Ajax',
headers:{'Accept':'application/json'}
});

Categories