Ajax array transforming into associative array - javascript

So, I'm building an API in Ruby on Rails and I'm trying to force an array to be sent through ajax.
It seems quite an easy task if it wasn't for the fact that the array is being received as an associative array other than regular array!
Basically an array with objects like:
[
{
"shipping_id":"1",
"option":"1"
},
{
"shipping_id":"2",
"option":"2"
}
]
becomes:
{"0"=>{"shipment_id"=>"1", "option"=>"1"}, "1"=>{"shipment_id"=>"2", "option"=>"2"}}
instead of
[{"shipping_id"=>"1", "option"=>"1"}, {"shipping_id"=>"2", "option"=>"2"}]
This is the JS I'm using to test the API:
function select_shipping(){
obj1 = {
"shipment_id": "1",
"option": "1"
};
obj2 = {
"shipment_id": "2",
"option": "2"
};
var shipments = [obj1, obj2];
var payload = {
user_options: shipments
}
$.post('/shipping/calculate/select', // url
payload, // data to be submit
function(data, status, jqXHR) {// success callback
console.log(data);
})
}
How can I transform my payload to go as a regular array instead of associative?

You can do the following:
Note that this solution can process any number of shipments.
var shipments = [
{
"shipping_id":"1",
"option":"1"
},
{
"shipping_id":"2",
"option":"2"
}
]
var payload = {}
shipments.map(
function(shipment, index){
payload["$".concat(index)] = shipment;
}
);
console.log(payload);

Related

How to loop through JSON and add values to object

So I am having trouble figuring out how to create an array with two objects, looping through my object and adding some values to those objects in Javascript. Currently I have the following mock response:
const mockResponse =
{
"errors": [
{
"errorKey": "ERROR_NO_DELIVERY_OPTIONS",
"errorParameters": [
{
"errorMessage": "ERROR_DELIVERY_OPTIONS_YOU_SELECTED_NOT_AVAILABLE_NOW",
"partNumbers": [
19308033,
19114798
]
},
{
"errorMessage": "Ship to Home not available for these orderItemId",
"orderItemIds": [
10315031,
10315032
],
"availableShipModeId": 13203
},
{
"errorMessage": "Pickup At Seller not available for these orderItemIds",
"orderItemIds": [
10222222,
10333333
],
"availableShipModeId": 13203
}
],
"errorMessage": "ERROR_NO_DELIVERY_OPTIONS",
"errorCode": "ERROR_NO_DELIVERY_OPTIONS"
}
]
}
I would like to have an array with two objects. One for the first error message("Ship to home...") and another for the second error message("Pickup at Seller..."). I would like to then loop through the JSON and add each "orderItemIds" to there respective object. For example, 10315031,10315032 would go to the first object and 10222222, 10333333 to the second.
You can use reduce to loop through your errors and use the errorMessage property as a key
const result = mockResponse.errors[0].errorParameters.reduce((prev, item) => {
const { errorMessage, orderItemIds } = item;
if (prev[errorMessage]) {
prev[errorMessage] = [...prev[errorMessage], ...orderItemsIds];
} else {
prev[errorMessage] = orderItemIds
}
return prev
}, {})
Let me know if this does answer your question

Loop to get value based on key name

Below is the JSON response I am getting. From this JSON response, I want to get the value of "fees" based on "detailComponent" with "FULL_FEE" only. But, somehow it gets the last value of "detailComponent" with "SUB_FEE" or others which is not correct.
I am sure not how to make this for loop condition to fix my issue. Can help to guide pls?
let data = {
"status": "SUCCESS",
"result": {
"originData": {
"detailType": "MSG",
"origin": [
{
"details": [
{
"detailComponent": "FULL_FEE",
"fees": 13564.00
},
{
"detailComponent": "SUB_FEE",
"fees": 8207.60
}
]
}
]
}
}
}
var getData = data.result.originData.origin[0].details[0].detailComponent;
console.log('getData: ', getData);
You can convert the array into a dictionary by the key (detailComponent) and the number (fees).
// Create Array
var items = [];
// Loop Through It
data.result.originData.origin[0].details.forEach((el, index) => items[el.detailComponent] = el.fees);
// Test
console.log(items["FULL_FEE"]);

How to check if a value exists in an JSON key that has an array of values

say I have the following JSON:
{
"selfExclusionMessage":{
"accountId":989898,
"expired":"false",
"userId":"37327513",
"products": [
"arcade", "vegas", "ex"
]
}
}
How can I check that a specific value is present in the products key array. For example if "arcade" value is present there. I would like to have an if statement that checks values in products array and do different things for each of the values ( arcade, vegas, ex), sometimes all three of the values will be present and sometimes only 1 or 2.
You just have to parse it with JSON.parse. The you can use includes array prototype to check if the value is in the array.
const data = JSON.parse(json)
const { products } = data.selfExclusionMessage
if (products.includes('arcade')) {
// do your stuff here
}
You can use conditional (ternary) operator with includes():
var jsonData = {
"selfExclusionMessage":{
"accountId":989898,
"expired":"false",
"userId":"37327513",
"products": [
"arcade", "vegas", "ex"
]
}
}
function isExists(data, key, value){
return jsonData.selfExclusionMessage[key].includes(value)? 'Exists' : 'Does not exists';
}
console.log(isExists(jsonData,'products','arcade'));
console.log(isExists(jsonData,'products','arcadexyzzzzzz'));
How about
let o = JSON.parse(myJSON);
for (let v of Object.values(o)) {
if (Array.isArray(v)) return Array.includes("arcade");
else return false;
}
Explanation: (1) Parse JSON into an object (2) check all object values for arrays (3) if there's an array, check to see if it has the desired value
var JSON = {
"selfExclusionMessage": {
"accountId": 989898,
"expired": "false",
"userId": "37327513",
"products": [
"arcade", "vegas", "ex"
]
}
};
if ("products" in JSON.selfExclusionMessage) {
console.log('Exist!');
if (JSON.selfExclusionMessage.products.includes("vegas")) {
console.log("includes");
} else {
console.log("!includes");
}
} else {
console.log('!Exist');
}
Note:- Simple way to solve this issue is to identify that object exists, then object key exists, then you check array includes value by includes method.
function searchValue( json, value ) {
return Array.isArray(json.selfExclusionMessage.products) && json.selfExclusionMessage.products.includes( value );
}

Handling key value pair in response

I have the following response.
response: {
"json": {
"response":{
"servicetype":"",
"functiontype":"",
"statuscode":"0",
"statusmessage":"Success",
"data":
[
{
"graphtype":"headcountgraph",
"xlabel":"state",
"ylabel":"count",
"s1":"contact",
"s2":"User",
"data":
[
"Total Contacts: 1 Users: 36",
[
{
"x":"India",
"s1":"3",
"s2":"3",
"lat":"22",
"long":"77"
}
]
]
}
]
}
}
};
I need to Assign $scope.state = India,
How to fetch that ? I have tried giving $scope.state = json.response.data[0].data[1][0].x, which returns undefined data.
The thing is it has key and entry. I really lacking to fetch entry values from the code.
I gave code this way
$.each(data, function(key, entry) { x.push(parseInt(entry.x)});
but it gives me values [india] in my console.
Try giving $scope.state = response.json.response.data[0].data[1][0].x ;
Your statement doesn't start from the root response object.
You were very close.
json.response.data[0].data[1]
returns the following object:
{"x":"India","s1":"3","s2":"3","lat":"22","long":"77"}
You can filter by the x key with:
json.response.data[0].data.filter(o => o[0].x == "India")[0];

Accessing JSON objects from objects without titles in JQuery

I am receiving this JSON file back from an AJAX call:
[
{
"LINKNAME": "Annual Training",
"HITS": 1
},
{
"LINKNAME": "In Focus Newsletter",
"HITS": 1
},
{
"LINKNAME": "NITA (secured)",
"HITS": 1
},
{
"LINKNAME": "Your Current Events",
"HITS": 1
},
]
Here is my AJAX call:
$(document).ready(function(e) {
$.ajax({
method: "GET",
url: url,
}).done(function(api) {
console.log(api);
var obj = JSON.parse(api),
totRes = Object.keys(obj).length;
$.each(obj.children, function (index, value) {
alert(value);
});
}).fail(function( jqXHR, textStatus ) {
alert('Service Catalog: Error loading '+jqXHR+' data. Request fail caused by: '+textStatus);
});
});
I need to be able to extract the data from the JSON and use it but since the JSON objects aren't gioven a title then I am unsure how to extarpolate the data inside the inner object. Thanks in advance. Please ask if you do not understand my question.
Your JSON is just an array of plain objects.
To iterate over an array, you can use various methods. Since you're using jQuery, I'll just suggest $.each:
var arr = JSON.parse(api);
$.each(arr, function(i, obj) {
// access whatever property you want... obj[LINKNAME] or whatever
});
You can also use Array.prototype.forEach, or even just your basic for loop:
arr.forEach(function(obj) {
// obj is the current plain object... e.g. { LINKNAME: 'whatever', HITS: 0 }
});
I would also consider paying attention to how you are referring to the objects that you are receiving. While it is true that arrays are objects, and plain objects are objects, I would probably stick to referring to an array as an array, and a plain object as an object. This is because what you are receiving, in the form of JSON, is an array object of plain objects (or more simply, an array of objects).
Calling the array an "object" and referring to it as obj may confuse you when reading through the code quickly (yes, it is a good abstraction for potential extensibility if you end up not always receiving an array, but that's not the case here.)
Also, to once you have access the object in the each loop, you can iterate over the properties of the object if you need to (taken from this answer):
var obj = {
"a": 1,
"b": 2,
"c": 3
};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
alert("prop: " + prop + " value: " + obj[prop])
}
}
First, you can add the setting dataType: 'json' when you send a request. This way you'll have api as javascript array.
Then you'll be able to iterate it via javascript for.
$.ajax({
method: "GET",
url: url,
dataType: "json"
}).done(function(api) {
for (var i = 0; i < api.length; i++) {
var name = api[i]["LINKNAME"],
hits = api[i]["HITS"];
// ...
}
// ...
$(document).ready(function(e) {
$.ajax({
method: "GET",
url: url,
}).done(function(api) {
if (api && api.length > 0) {
api.forEach(function (item) {
console.log(item); // logs whole object
console.log('item name %s', item.LINKNAME);
console.log('item hits %s', item.HITS);
});
}
}).fail(function( jqXHR, textStatus ) {
alert('Service Catalog: Error loading '+jqXHR+' data. Request fail caused by: '+textStatus);
});
});
You can filter the results to make sure you're only using objects that contain both 'LINKNAME' and 'HITS' pretty easily:
.done(function(api) {
if (api && api.length > 0) {
var objs = api.filter(function (item) {
return item.hasOwnProperty('LINKNAME') && item.hasOwnProperty('HITS');
});
objs.forEach(function (item) {
console.log(item); // logs whole object
console.log('item name %s', item.LINKNAME);
console.log('item hits %s', item.HITS);
});
}
});

Categories

Resources