How to post JSON array of objects using JQuery - javascript

I am using Javascript/jQuery in the Chrome browser console to post data to a page. (I'm doing this in Shopify admin, because it doesn't have the capability to bulk import shipping rates).
This is the code I am using:
make_weight_based_shipping_rate(8267845, 98, 99, 'Test Shipping Rate', 59);
function make_weight_based_shipping_rate(cid, minWeight, maxWeight, name, price) {
$.post('/admin/weight_based_shipping_rates.json', {
weight_based_shipping_rate: {
country_id: cid,
name: name,
offsets: [{disabled:true, offset:0, province_id:145570341}, {disabled:true, offset:0, province_id:145570345}],
weight_high: maxWeight,
weight_low: minWeight,
price: price
}
});
}
It works well, except for one line of my request which has an array of objects - the line that begins with 'offsets'.
If I only have one JSON object on this line, and not in an array (by excluding the square brackets), this code works. However, as an array, Shopify comes back with the error '422 (Unprocessable Entity)' and in the body of the response it says '{"errors":{"shipping_rate_offsets":["is invalid"]}}'.
Am I formatting this JSON object incorrectly? If not, is there some other way I can achieve this rather than use the JQuery Post method?

I eventually figured it out. By default, JQuery POST and AJAX requests are encoded as "application/x-www-form-urlencoded". This works most of the time, but it seems to fail when it gets an array such as 'offsets'.
To get around this, first I had to use the JSON.stringify() function on the data being submitted. Then prior to making the POST, I used the ajaxSetup() function to set the content-type to "application/json". My modified code is now:
make_weight_based_shipping_rate(8267845, 98, 99, 'Test Shipping Rate', 59);
function make_weight_based_shipping_rate(cid, minWeight, maxWeight, name, price) {
$.ajaxSetup({
contentType: "application/json; charset=utf-8"
});
$.post('/admin/weight_based_shipping_rates.json', JSON.stringify({
weight_based_shipping_rate: {
country_id: cid,
name: name,
offsets: [{disabled:true, offset:0, province_id:145570341}, {disabled:true, offset:0.00, province_id:145570345}],
weight_high: maxWeight,
weight_low: minWeight,
price: price
}
}));
}
I hope this helps others.

Related

How to Display Value Created from API Onto My Browser?

So I am working with this API and it auto calculates the delivery fee based on the address you input.
Here's the API docs I am using
https://developer.doordash.com/en-US/api/drive#operation/DeliveryQuote
So when I add my values to my form and get my data, it logs the fee in my console like this
My issue is how do I get this value from the data field?
I tried to do
const response = await client.createDelivery(
{
order_value: req.body.item1,
fee: fee,
tip: req.body.item1,
},
console.log(fee)
);
console.log(response);
res.send(response);
}
)
But it says fee is not defined?
I also tried fee: "" and that doesn't work either.
I even put console.log(data.fee) and it says data is not defined
My last attempt I change it to console.log(response.fee) and it still showed undefined in the console?
How do I even get the fee value to console.log?
Note I am using express and for my tip value I have my input form named "item1" so I can access it by saying req.body.item1 to get that value
However, for the fee value its auto generated by the API, so I can't change it or update it manually myself.
Try using
console.log(response.data.fee)
And I am not sure what your client.createDelivery does. If it sends response, then you need to display it like
const response = await client.createDelivery(
{
order_value: req.body.item1,
fee: fee,
tip: req.body.item1,
},
console.log(fee)
).then((res) => res.json()).then((resData) => console.log(resData.data.fee));
this is what the return object looks like
{
data {
currency: 'USD',
fee: 975,
otherData: otherData,
}
}
what you must do to fix your problem is first dive into the data object then retrieve fee from that object like data.fee
const response = await client.createDelivery(
{
order_value: req.body.item1,
fee: data.fee, // changed from fee to data.fee
tip: req.body.item1,
},
console.log(data.fee)
);
without retrieving it from the data object there would be no fee object to grab which is whats making it undefined...

Custom parameters for bootstrap-table server side pagination

I have a service created with spring boot, for which I am trying to display its data using the bootstrap-table library.
My service allows pagination with the query parameters ?page=x&size=y, where page starts at 0.
The response for the query returns something that looks like this:
{
"_embedded": {
"catalogueOrders": [ .... ]
},
"page": {
"size": 20,
"totalElements": 11,
"totalPages": 1,
"number": 0
}
}
Where _embedded.catalogueOrders contains all the data, and page contains the totals.
I tried configuring my table as following:
$('#orderTable').bootstrapTable({
url: "http://localhost:8088/catalogueOrders?orderStatus=" + orderState,
columns: [
{
field: 'orderId',
title: 'Order ID'
},
{
field: 'priority',
title: 'Priority'
}
],
pagination: true,
sidePagination: 'server',
totalField: 'page.totalElements',
pageSize: 5,
pageList: [5, 10, 25],
responseHandler: function(res) {
console.log(res)
return res["_embedded"]["catalogueOrders"]
}
})
This is able to retrieve and display the data, however it returns all the results, clearly due to it not knowing how to apply the pagination. Total elements doesn't seem to be retrieved either, as the table displays Showing 1 to 5 of undefined rows. Also, if I replace the responseHandler with dataField: '_embedded.catalogueOrders', it's no longer displaying the data.
How do I configure the query parameters needed for pagination?
And am I doing anything wrong when I try and configure dataField and totalField?
Figured it out:
Not sure what was wrong with the dataField and totalField, but it seems to not work with nested fields. To resolve this, I formatted the response into a new object inside responseHandler:
dataField: 'data',
totalField: 'total',
responseHandler: function(res) {
return {
data: res["_embedded"]["catalogueOrders"],
total: res["page"]["totalElements"]
}
}
As for the query parameters, by default, bootstrap-table provides the parameters limit and offset. To customize that and convert to size and page like in my case, the queryParams function can be provided:
queryParams: function(p) {
return {
page: Math.floor(p.offset / p.limit),
size: p.limit
}
}
one, yes, it doesn’t work with nested fields. if you want to use nested fields, try on sass code (get the compiler, just search up on web, there’s plenty of posts on the web).
two, i’m not exactly sure what you’re talking about, but you can set up a css variable
:root{
/*assign variables*/
—-color-1: red;
—-color-2: blue;
}
/*apply variables
p {
color: var(-—color-1):
}
you can find loads of info on this on the web.

iron-ajax ignores duplicate params

So I am using iron-ajax's params to send queries to my api; the params field of the ajax calls this function params="ajaxParams". The problem i've ran into is that when I call amount: ... more than once the second one replaces it in the query.
//enters praramaters into the iron-ajax params, this automatically
// gets added onto the ajax link, and will generate a new request when a change happens.
_getParams: function(searchQuery, amountMin, amountMax){
return{
name: searchQuery,
amount: '>=' + amountMin,
amount: '<=' + amountMax
}
},
This is what the encoded query string looks like in the xhr request:
path/to/api/data?name=bob&amount=%3C%3D50000
And the query for this was:
name: 'bob',
amount: '>=' + 5000,
amount: '<=' + 50000
Additionally Ive tried:
return{
name: searchQuery,
amount: '>' + amountMin + '&amount<' + amountMax
}
but the out put just gets encoded into:
path/to/api/data?name=bob&amount=%3E5000%26amount%3C50000
To summarise I am trying to get the following query from iron-ajax params, but it seems that the params argument wont accept having duplicate parameters:
path/to/api/data?name=bob&amount=%3E5000&amount=%3E50000
Edit:
as Gar pointed out this seems to be a js issue where 2 object properties are bieng returned, as a work around to this I tried to get rid of the params and just add the variables to the api url:
<iron-ajax auto
url="path/to/api/data?name={{searchQuery}}
&amount=>={{amountMin}}
&amount=<={{amountMax}}"
handle-as="json"
method="GET"></iron-ajax>
this will break the url into this though
path/to/api/data?name=%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&amount=%3E=5000%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&amount=%3C=50000

Malformed request when creating billing plan

So I a using the node paypal-rest-sdk module and I'm trying to create a billing plan. Using the documentation here I made this JSON:
const billingPlanAttributes = {
name: 'Subscription',
description: 'Monthly subscription plan',
type: 'INFINITE',
payment_definitions: [{
name: 'Regular monthly infinite payments',
type: 'REGULAR',
frequency_interval: '1',
frequency: 'MONTH',
cycles: '0',
amount: {
currency: 'USD',
amount: '4.99',
},
}],
merchant_preferences: {
cancel_url: 'http://localhost:3000/subscribe/cancel',
return_url: 'http://localhost:3000/subscribe/return',
auto_bill_amount: 'YES',
},
};
But when using the paypal.billingPlan.create(... function I get the error 'MALFORMED_REQUEST', 'Incoming JSON request does not map to API request'. So I guess my JSON is not in the correct format or I'm missing something that is need.
The documentation has a charge_models key but it does not mention that it is required unlike other keys.
If you can point me in the right direction that would be great.
Edit: changed the return url and cancel url to include the full domain but still same error.
There could be more to this, but I noticed one thing wrong with your JSON. Remove commas for items last in a list. After 'amount' and 'merchant_preferences'. JSON is picky.
late answer, I know, but ran in exactly the same issue than you.
In the create function of the billing plan
public function create($apiContext = null, $restCall = null)
{
$payLoad = $this->toJSON();
$json = self::executeCall(
"/v1/payments/billing-plans/",
"POST",
$payLoad,
null,
$apiContext,
$restCall
);
$this->fromJson($json);
return $this;
}
I found out, that the toJSON method always returned false. Why the hell!?!
I did the same as you did and copied the complete sample code into my code. Then it worked as expected. Now I checked, what the difference was in to my code.
I realized, that I used an umlauts (ä,ü,ö) in the name and description of the billing plan. I changed the umlauts to
'ä' => 'ae',
'ö' => 'oe'
'ü' => 'ue'
Then it worked fine! Maybe someone else is running in this issue, too.

Creating an envelope from a template returning "UNSPECIFIED_ERROR"

When I try to create an envelope from a template I get a response of:
{ errorCode: 'UNSPECIFIED_ERROR',
message: 'Non-static method requires a target.' }
Here's what I'm doing so far:
First I login, which returns
{ loginAccounts:
[ { name: '*****',
accountId: '*****',
baseUrl: 'https://demo.docusign.net/restapi/v2/accounts/******',
isDefault: 'true',
userName: '***** ********',
userId: '*******-*****-*****-*****-*********',
email: '********#*******.com',
siteDescription: '' } ] }
So then I take the baseUrl out of that response and I attempt to create the envelope. I'm using the hapi framework and async.waterfall of the async library, so for anyone unfamiliar with either of these my use of the async library uses the next callback to call the next function which in this case would be to get the url for the iframe, and with our usage of the hapi framework AppServer.Wreck is roughy equivalent to request:
function prepareEnvelope(baseUrl, next) {
var createEntitlementTemplateId = "99C44F50-2C97-4074-896B-2454969CAEF7";
var getEnvelopeUrl = baseUrl + "/envelopes";
var options = {
headers: {
"X-DocuSign-Authentication": JSON.stringify(authHeader),
"Content-Type": "application/json",
"Accept": "application/json",
"Content-Disposition": "form-data"
},
body : JSON.stringify({
status: "sent",
emailSubject: "Test email subject",
emailBlurb: "My email blurb",
templateId: createEntitlementTemplateId,
templateRoles: [
{
email: "anemailaddress#gmail.com",
name: "Recipient Name",
roleName: "Signer1",
clientUserId: "1099", // TODO: replace with the user's id
tabs : {
textTabs : [
{
tabLabel : "acct_nmbr",
value : "123456"
},
{
tabLabel : "hm_phn_nmbr",
value : "8005882300"
},
{
tabLabel : "nm",
value : "Mr Foo Bar"
}
]
}
}
]
})
};
console.log("--------> options: ", options); // REMOVE THIS ====
AppServer.Wreck.post(getEnvelopeUrl, options, function(err, res, body) {
console.log("Request Envelope Result: \r\n", JSON.parse(body));
next(null, body, baseUrl);
});
}
And what I get back is:
{ errorCode: 'UNSPECIFIED_ERROR',
message: 'Non-static method requires a target.' }
From a little googling it look like 'Non-static method requires a target.' is a C# error and doesn't really give me much indication of what part of my configuration object is wrong.
I've tried a simpler version of this call stripping out all of the tabs and clientUserId and I get the same response.
I created my template on the Docusign website and I haven't ruled out that something is set up incorrectly there. I created a template, confirmed that Docusign noticed the named form fields, and created a 'placeholder' templateRole.
Here's the templateRole placeholder:
Here's one of the named fields that I want to populate and corresponding data label:
As a side note, I was able to get the basic vanilla example working without named fields nor using a template using the docusign node package just fine but I didn't see any way to use tabs with named form fields with the library and decided that I'd rather have more fine-grained control over what I'm doing anyway and so I opted for just hitting the APIs.
Surprisingly when I search SO for the errorCode and message I'm getting I could only find one post without a resolution :/
Of course any help will be greatly appreciated. Please don't hesitate to let me know if you need any additional information.
Once I received feedback from Docusign that my api call had an empty body it didn't take but a couple minutes for me to realize that the issue was my options object containing a body property rather than a payload property, as is done in the hapi framework.

Categories

Resources