How do I add multiple HTTP headers dynamically in an AJAX call?
I have an array of objects containing which headers to add and their values like:
[
{
"headerName": "foo",
"headerValue": "bar"
},
{
"headerName": "some",
"headerValue": "text"
},
{
"headerName": "random",
"headerValue": "values"
}
]
I want to iterate over the array and add headers with its corresponding values in my AJAX call.
$.ajax({
url: 'foo/bar',
...
headers: {
'key[0]':'value[0]',
'key[1]':'value[1]',
(to n times)
},
...
});
I can use jQuery and Knockout in my project. Please help.
Thanks in advance.
In jQuery you can try something like:
headers = {}
$.each(array,function(i,val){
headers.key[i] = array[i].headerValue;
})
Or maybe this should work:
headers = {}
$.each(array,function(i,val){
headers.key[i] = val["headerValue"]; //since val is a JSON object here.
})
I haven't tried executing this code, you can refer to this for help.
Related
I have an endpoint which I call with Axios and the response looks like (for example):
items: [
{
url: "https://api.example1...",
expirationDate: "2019-11-15T00:00:00+01:00"
},
{
url: "https://api.example2...",
expirationDate: "2019-12-20T00:00:00+01:00"
},
{
url: "https://api.example3...",
expirationDate: "2020-01-17T00:00:00+01:00"
},
...and so on.
If I go to one of the url:s in the browser the structure of the JSON is:
fooBar: {
url: "https://api.foo...",
id: "123",
type: "INDEX",
source: "Foobar",
quotes: {
url: "https://api.bar..."
}
},
I need to get the quotes of the two first url:s in items:[] dynamically because they will disappear when the 'expirationDate' is older than today's date.
How can this be achieved? Thanks in advance!
If I understand the requirements correctly you need to:
get the list of items
get item details for first two items (to extract links to quotes)
get quotes for first two items
You can use promise chaining to execute these operations maintaining the order:
const getQuotes = (item) => axios.get(item.url)
.then(resp => axios.get(resp.data.fooBar.quotes.url));
axios.get('/items') // here should be the url that you use to get items array
.then(resp => resp.data.slice(0, 2).map(getQuotes))
.then(quotes => Promise.all(quotes))
.then(quotes => {
console.log(quotes);
});
Please find my proposal below. I gave two examples. You can get the whole quotes object, or just the URL inside the quotes object.
This is just a console log, but you can easily ie. append this data to a div in the html or pass this URL to some other function.
$(function() {
const address = 'https://api.example1...';
function loadQuotes() {
$.ajax({
url: address,
dataType: 'json',
}).done(function(response) {
response.forEach(el => {
console.log(`el.quotes`);
// or if you want to be more specific console.log(`el.quotes.url`);
});
});
}
loadQuotes();
});
If these are nested objects, just append fooBar.
For example change the .done part to:
.done(function(response) {
let qqq = response.quotes
quotes.forEach(el => {
console.log(`el.quotes`);
// or if you want to be more specific console.log(`el.quotes.url`);
});
I'm having an issue with building a private Zapier integration since Zapier can only use arrays as outputs instead of objects. The array I needs to call is nested 2 levels into my API results, and the key it needs to call is a variable unique to the task called (but I can I can make it part of the input data).
So to get the correct array, the javascript would need to be something like "return results.custom_field_values[bundle.inputData.id]", but I can't find a way to get the input data variable to be accepted in the results like.
Is this possible? I couldn't find a solution in the support documentation.
Here is the call I'm making:
const options = {
url: `https://api.mavenlink.com/api/v1/custom_field_values.json?subject_type=story&with_subject_id=${bundle.inputData.subject_id}& custom_field_name=Active Assignee`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`,
'Accept': 'application/json'
},
params: {
'subject_id': bundle.inputData.with_subject_id,
'display_value': 'Active Assignee'
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
// You can do any parsing you need for results here before returning them
return results.custom_field_values[bundle.inputData.id];
});
Here is my result when I call just results.custom_field_values:
{
"233451615": {
"can_edit": true,
"subject_type": "story",
"account_id": 4150797,
"subject_id": 385046515,
"updated_at": "2019-03-18T13:54:28-07:00",
"value": [
638945
],
"display_value": "Irma Davila",
"setter_id": "10976265",
"custom_field_id": "181017",
"created_at": "2019-03-05T07:00:15-08:00",
"custom_field_name": "Active Assignee",
"type": "single",
"id": "233451615"
}
}
What I'm trying to do is call only the array within the object that in this case is "233451615" (It's the same as the ID). However, even though the object is different every time, it can be provided as a variable via the input.
Thanks to anyone willing to help!
You need to use [] notation Ref
Change this
"return results.custom_field_values.{bundle.inputData.id}"
to this
"return results.custom_field_values[bundle.inputData.id]"
Have you tried bracket notation instead of dot notation?
something like this :
results.custom_field_values[{bundle.inputData.id}]
Also make sure that bundle.inputData.id is the correct value.
I'm finding myself in some troubles while testing my API with Cypress. (I'm using version 2.1.0)
I am sending a request to my endpoint, and want to verify how it is reacting when I am sending an empty array as a parameter. The problem is that somehow, Cypress must be parsing the body I am giving him, and removing the empty array.
My code is the following :
cy.request({
method: 'PUT',
url,
form: true,
body: {
name: 'Name',
subjects: []
}
})
.then((response) => {
expect(response.body).to.have.property('subjects');
const { subjects } = response.body;
expect(subjects.length).to.eq(0);
});
// API receives only the parameter name, and no subjects
When I am sending an empty array of subjects, the endpoint will delete all the associated subjects, and return the object with an empty array of subjects. It is working as it should, and my software in use is working as it should.
When Cypress is sending this request, the endpoint does not receive the parameter subjects. Which is for me a very different thing : I should not touch the subjects in this case.
Is there a way to avoid this "rewriting" by Cypress and send the body as I write it ?
The test works when setting form: false.
it.only('PUTs a request', () => {
const url = 'http://localhost:3000/mythings/2'
cy.request({
method: 'PUT',
url: url,
form: false,
body: {
name: 'Name',
subjects: []
}
})
.then((response) => {
expect(response.body).to.have.property('subjects');
const {
subjects
} = response.body;
expect(subjects.length).to.eq(0);
});
})
I set up a local rest server with json-server to check out the behavior.
If I try to PUT a non-empty array with form: true
cy.request({
method: 'PUT',
url: url,
form: true,
body: {
name: 'Name',
subjects: ['x']
}
})
looking at db.json after the test has run, I see the item index migrating into the key,
"mythings": [
{
"name": "Name",
"subjects[0]": "x",
"id": 2
}
],
so perhaps form means simple properties only.
Changing to form: false gives a proper array
{
"mythings": [
{
"name": "Name",
"subjects": ['x'],
"id": 2
}
],
}
which can then be emptied out by posting an empty array.
I'm trying to add users to a Custom Audience in Facebook, and I believe I have bungled the payload piece of the request below.
The error returned is:
(#100) Missing required parameter: payload
For reference, I'm generating the hash using Crypto-JS. Here's the code I tried:
var payload = { "payload": [{ "schema": "EMAIL_SHA256", "data": [hash] }]};
FB.api('/000000000/users', 'post', payload, function (response) {
if (response && !response.error) {
alert("This worked");
} else {
alert(response.error.message);
}});
The FB.api documentation shows that it expects 'payload' as a JSON object (https://developers.facebook.com/docs/marketing-api/custom-audience-targeting/v2.3#add). I just haven't been able to figure out the correct syntax yet. The example in the Facebook API documentation shows the following:
payload = {"schema":"EMAIL_SHA256","data":["HASH", "HASH", "HASH" ]}
Here's what I have so far (not working):
var payload = { "payload": [{ "schema": "EMAIL_SHA256", "data": [hash] }]};
Can anyone assist with the syntax? I've found plenty of examples of JSON objects and arrays, but I haven't seen anything that matches this format:
payload = {"schema":"EMAIL_SHA256","data":["HASH", "HASH", "HASH" ]}
For the benefit of any other JS/JSON novices, I finally figured it out after more experimentation:
var payload = { "payload": { "schema": "EMAIL_SHA256", "data": [hash] } };
suppose I have a config javascript file:
window.Config = {};
Config.UI = {
"Area": {},
"Layer": {},
"Sprites": {},
"Audio": {}
};
Config.UI.Area = {
"prop": {
"uuid": {
"_type": "string",
},
"frame": {
"_type": "rect",
"_value": {
"x": "0",
},
"_aka": "frame"
},
"zIndex": {
"_type": "string",
}
},
then I want use $.ajax to read this file:
$.ajax({
url:'js/config.js',
success:function (data, textStatus) {
console.log(data);
}
})
the question is how can I get some key's value in the config,by use the data $.ajax return?
like the "Config.UI" or the 'uuid' in ui.area.prop?Or can I convert them to json?
Rather than use AJAX, why not just insert a script?
var script = $('<script>');
script.attr('type', 'text/javascript');
script.attr('src', 'js/config.js');
script.bind('load', function() {
// use window.Config
});
script.appendTo('head');
icktoofay has a good suggestion, and the issue with the jQuery.ajax call looks to be a missing dataType: 'script' option which will evaluate the response and should give you object access. You might want to look into jQuery.getscript() as well.
I find it very useful and powerful to store data on the server as javascript objects and read them using Ajax. And it is very easy to do. Let me give you an example from an educational application I have written.
This is an example table of contents file (l1contents.js) that I would store on the server:
{
title : "Lesson 1",
topics : [
{name : "Topic 1", file : "l1t1data.js" },
{name : "Topic 2", file : "l1t2data.js" },
]
}
This is the javascript code I use to process the file:
$.ajax({
url : contentsFileName, // would be set to 'l1contents.js'
dataType : 'text', // yes this is correct, I want jquery to think this is text
cache : false,
success: function(data) {
var contentsObj = eval('(' + data + ')');
var lessonTitle = contentsObj.title;
for (var i = 0; i < contentsObj.topics.length; i++) {
var topic = contentsObj.topics [i];
// process topic.name and topic.file here
}
}
});
Obviously, this is simplified, but hopefully you get the idea. I simply use eval to set the object. And note that I don't even need any javascript code defining the structure of contentsObj. (I, of course, do have extensive comments defining the structure of my objects, but they are simply comments, not code.)
if your json file contains json data than you can use parseJSON() , toJSON() method.
and another solution is use eval(), this conver json data to javascript object so you can easly get a value by giving key.