How to access variable from Ajax FormData.append? - javascript

I am sending an uploaded file from my HTML form to my server and am trying to add a custom attribute to FormData(), but it's not showing up on my server side.
I add my custom attribute by doing var formData = new FormData();, then appending by doing formData.append("airlinename",airline_name);, but once I get the data on the Server side, I look in the req object and can't find airlinename. How do I access my custom attribute?
I am able to access the file just fine, but I can't find how to access the custom attribute I appended to formData.
HTML Form
<form role="form">
<input type="text" id="load_db_name" name="load_db_name">
<input type="file" id="load_db_dir" name="load_db_dir">
</form>
<button id="load_generateDiagram" onClick="loadPastDiagram();" type="button">Load</button>
Client JS
function loadPastDiagram()
{
var db_dir = document.getElementById('load_db_dir').files[0] || null;
var _files = [db_dir];
var airline_name = document.getElementById('load_db_name').value.trim();
loadDiagram(airline_name,_files);
}
function loadDiagram(airline_name, files)
{
var formData = new FormData();
for (var f in files) {
formData.append("files", files[f]);
}
formData.append("airlinename",airline_name); //<--- can't find this on the server side
$.ajax({
url: '/loadDiagram',
type: 'POST',
success: function(res) {
console.log("Success");
},
error: function(err) {
console.log("Error ",err);
},
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
}
Server JS
app.post('/loadDiagram', function(req,res){
console.log("[FILES]" + JSON.stringify(req.airlinename));
console.log("[FILES]" + JSON.stringify(req.files.airlinename));
console.log("[FILES]" + JSON.stringify(req.files.files));
});
Output
[DEV] [FILES]undefined
[DEV] [FILES]undefined
[DEV] [FILES]{
"fieldName": "files",
"originalFilename": "Tool_fresshhh.tar.gz",
"path": "../Output-Files/2833-fwh0ql.tf9od2t9.gz",
"headers": {
"content-disposition": "form-data; name=\"files\"; filename=\"Tool_fresshhh.tar.gz\"",
"content-type": "application/x-gzip"
},
"ws": {
"_writableState": {
"objectMode": false,
"highWaterMark": 16384,
"needDrain": true,
"ending": true,
"ended": true,
"finished": true,
"decodeStrings": true,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": false,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 0,
"prefinished": true,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree": {
"next": {
"next": null,
"entry": null
},
"entry": null
}
},
"writable": false,
"domain": null,
"_events": {
"error": [null],
"close": [null]
},
"_eventsCount": 2,
"path": "../Output-Files/2833-fwh0ql.tf9od2t9.gz",
"fd": null,
"flags": "w",
"mode": 438,
"autoClose": true,
"bytesWritten": 449781,
"closed": true
},
"size": 449781,
"name": "Tool_fresshhh.tar.gz",
"type": "application/x-gzip"
}
Versions
jQuery v1.11.1
Express Version: 3.14.0
Node Version: v6.5.0

I know this is "uncool"...
But I saw this question as it was posted, more than 1 hour ago, and saw (quite fast!!) the solution posted as a comment.
I waited on him or her to post it, so I could learn something.
But since Jaromanda X was actually last seen 5 minutes ago without posting the answer...
I guess he or she is not really interested about rep. points!
So just to mark this question as answered...
;)
Server JS
app.post('/loadDiagram', function(req,res){
console.log("[FILES]" + JSON.stringify(req.body.airlinename)); // <--
console.log("[FILES]" + JSON.stringify(req.files.files));
});
«First one to post it, gets it! »

Related

Having trouble trying to grab a specific key value from Stripe API using dot notation with JSON

I'm pulling data from the Stripe API from a test invoice. I'm trying to narrow down to pull a specific key value pair using dot notation, but I'm having trouble pulling the data from a specific key value as it seems nester deeper than the rest of the data (not sure if that's the right terminology).
The data I'm trying to pull the data from is from period: end: and from period: start: roughly from lines 44-46.
If I use dot notation in my code it works when the key value pair is on the same line, such as sheet.getRange(3,2).setValue([content.amount_due]);. But it seems as if "period: end" and "period: start" are nested deeper.
I tried doing something like [content.lines.data.period.end] but it didn't work. It returns this error: TypeError: Cannot read property "end" from undefined.
Here's the full data pulled from the API (note: "xxxxxxxxxxxxxxxx" represents data that's been hidden):
""id"": ""in_xxxxxxxxxxxxxxxx"",
""object"": ""invoice"",
""amount_due"": 800,
""amount_paid"": 800,
""amount_remaining"": 0,
""application_fee"": null,
""attempt_count"": 1,
""attempted"": true,
""auto_advance"": false,
""billing"": ""charge_automatically"",
""billing_reason"": ""subscription_cycle"",
""charge"": ""ch_xxxxxxxxxxxxxxxx"",
""closed"": true,
""created"": 1552077120,
""currency"": ""usd"",
""custom_fields"": null,
""customer"": ""cus_xxxxxxxxxxxxxxxx"",
""date"": 1552077120,
""default_payment_method"": null,
""default_source"": null,
""description"": null,
""discount"": null,
""due_date"": null,
""ending_balance"": 0,
""finalized_at"": 1552080770,
""footer"": null,
""forgiven"": false,
""hosted_invoice_url"": ""https://pay.stripe.com/invoice/invst_xxxxxxxxxxxxxxxx"",
""invoice_pdf"": ""https://pay.stripe.com/invoice/invst_xxxxxxxxxxxxxxxx/pdf"",
""lines"": {
""object"": ""list"",
""data"": [
{
""id"": ""sub_xxxxxxxxxxxxxxxx"",
""object"": ""line_item"",
""amount"": 800,
""currency"": ""usd"",
""description"": null,
""discountable"": true,
""livemode"": false,
""metadata"": {
},
""period"": {
""end"": 1554755515,
""start"": 1552077115
},
""plan"": {
""id"": ""xxxxxxxxxxxxxxxx"",
""object"": ""plan"",
""active"": true,
""aggregate_usage"": null,
""amount"": 400,
""billing_scheme"": ""per_unit"",
""created"": 1407529859,
""currency"": ""usd"",
""interval"": ""month"",
""interval_count"": 1,
""livemode"": false,
""metadata"": {
},
""name"": ""sdf"",
""nickname"": null,
""product"": ""prod_xxxxxxxxxxxxxxxx"",
""statement_description"": null,
""statement_descriptor"": null,
""tiers"": null,
""tiers_mode"": null,
""transform_usage"": null,
""trial_period_days"": null,
""usage_type"": ""licensed""
},
""proration"": false,
""quantity"": 2,
""subscription"": null,
""subscription_item"": ""si_xxxxxxxxxxxxxxxx"",
""type"": ""subscription"",
""unique_line_item_id"": ""sli_xxxxxxxxxxxxxxx""
}
],
""has_more"": false,
""total_count"": 1,
""url"": ""/v1/invoices/in_xxxxxxxxxxxxxxxx/lines""
},
""livemode"": false,
""metadata"": {
},
""next_payment_attempt"": null,
""number"": ""77E3C02-0025"",
""paid"": true,
""payment"": ""ch_1xxxxxxxxxxxxxxxx"",
""payment_intent"": ""pi_xxxxxxxxxxxxxxxx"",
""period_end"": 1552077115,
""period_start"": 1549657915,
""receipt_number"": ""2258-2679"",
""starting_balance"": 0,
""statement_description"": null,
""statement_descriptor"": null,
""status"": ""paid"",
""status_transitions"": {
""finalized_at"": 1552080770,
""marked_uncollectible_at"": null,
""paid_at"": 1552080772,
""voided_at"": null
},
""subscription"": ""sub_xxxxxxxxxxxxxxxx"",
""subtotal"": 800,
""tax"": null,
""tax_percent"": null,
""total"": 800,
""webhooks_delivered_at"": 1552077123
}"```
[1]: https://stripe.com/docs/api/invoices/retrieve
data is an array, try content.lines.data[0].period.end.

How to get properties from json API when using fetch, cors?

I need to get properties by accessing this link.
fetch("https://pokeapi.co/api/v2/pokemon/28/").then(results => {
console.log(results);
})
I receive this respond in console.
Response {type: "cors", url: "https://pokeapi.co/api/v2/pokemon/28/",
redirected: false, status: 200, ok: true, …} body:(...) bodyUsed:true
headers:Headers {} ok:true redirected:false status:200 statusText:""
type:"cors" url:"https://pokeapi.co/api/v2/pokemon/28/"
proto:Response
But I expect to see something like this:
{ "forms": [ { "url":
> "https://pokeapi.co/api/v2/pokemon-form/28/", "name": "sandslash"
> } ], "abilities": [ { "slot": 3, "is_hidden": true,
> "ability": {
> "url": "name": "defense"
...
And so on...how can I get this data?
I can access it from their website pokeapi.co, but not from my app.
What I am doing wrong? Please, help me to understand!!
fetch("https://pokeapi.co/api/v2/pokemon/28/").then(results => { return results.json();
}).then(data => {
console.log(data);
})
This is a solution. It's strange, because few hours ago it was a different response.

How to link a JSON generated list to display the content of a different JSON file

I'm calling a JSON file (sections.json), and then accessing the array sections, looping through every item and appending the name value to a li. I wish to give this li a link (or click event) to display the articles names of the corresponding section on .sectionArticles. To access the articles of a specific section, I have to access a different JSON file (sections/{section id}/articles.json). I'm clueless on this last part... could someone point me out in the right direction?
Here is my current code so far:
$(function() {
// URLs
var zendeskUrl = 'https://myhelpcenter.zendesk.com/'
var sectionsUrl = zendeskUrl+'api/v2/help_center/pt-br/sections.json';
var articlesUrl = zendeskUrl+'api/v2/help_center/pt-br/articles.json?per_page=100';
$.ajax({
type: 'GET',
url: sectionsUrl,
success: function(data) {
data.sections.forEach(function(section) {
$('.sectionsList').append('<li class="sectionName">' + section.name + '</li>');
})
},
error: function() {
console.log("Error: sectionsUrl");
}
})
$.ajax({
type: 'GET',
url: articlesUrl,
success: function(data) {
data.articles.forEach(function(article) {
if (article.promoted == true) {
$('.promotedList').append('<li class="promotedName">' + article.name + '</li>');
}
})
},
error: function() {
console.log("Error: articlesUrl");
}
})
})
JSOM Sample:
List ALL Sections: /api/v2/help_center/sections.json
{
"sections": [
{
"id": 115001417087,
"url": "/api/v2/help_center/sections/115001417087.json",
"html_url": "/hc/sections/115001417087",
"category_id": 115000835587,
"position": 0,
"sorting": "manual",
"created_at": "2017-03-22T14:29:48Z",
"updated_at": "2017-06-13T20:01:01Z",
"name": "Section 1",
"description": "",
"locale": "",
"source_locale": "",
"outdated": false
}
],
"page": 1,
"previous_page": null,
"next_page": null,
"per_page": 30,
"page_count": 1,
"count": 8,
"sort_by": "position",
"sort_order": "asc"
}
List ALL Articles from Section {id}: /api/v2/help_center/sections/{id}/articles.json */
{
"count": 9,
"next_page": null,
"page": 1,
"page_count": 1,
"per_page": 30,
"previous_page": null,
"articles": [
{
"id": 115008623727,
"url": "/api/v2/help_center/articles/115008623727.json",
"html_url": "/hc/articles/115008623727",
"author_id": 20423232608,
"comments_disabled": true,
"draft": false,
"promoted": false,
"position": 0,
"vote_sum": 0,
"vote_count": 0,
"section_id": 115001417087,
"created_at": "2017-06-13T19:46:17Z",
"updated_at": "2017-06-13T19:59:28Z",
"name": "Some name",
"title": "Some title",
"body": "Some HTML",
"source_locale": "",
"locale": "",
"outdated": false,
"outdated_locales": [],
"label_names": []
}
],
"sort_by": "position",
"sort_order": "asc"
}
I don't know if I understood the question the right way, but I assume you load the section list in the beginning and then want to load articles only when requested.
Therefore I'd first store the section id in the section list, so I can reuse it later on.
$.ajax({
type: 'GET',
url: sectionsUrl,
success: function(data) {
data.sections.forEach(function(section) {
$('.sectionsList').append('<li class="sectionName" data-section-id="' + section.id + '">' + section.name + '</li>');
})
},
error: function() {
console.log("Error: sectionsUrl");
}
})
With .on('click'), you already went into the right direction but since the sections are generated after event binding took place, you need event delegation to react on your click.
you can read more on this here: https://learn.jquery.com/events/event-delegation/
Additionally, I added the empty() call to clear the article list. If there are previous results, you can move that line into the ajax success function. If you want to keep the old list as long as no valid response has been returned, in terms of usability, I wouldn't. Keeping it doesn't show the user that something is happening. They might wait a moment and click again and again and again and so on. Better rework the error function to show something in the list instead of the console.log.
$(".sectionsList").on("click", ".sectionName", function(){
clickedSectionId = $(this).data("sectionId");
$('.promotedList').empty(); //clear list of previous results
articlesUrl = zendeskUrl + 'api/v2/help_center/' + clickedSectionId + '/articles.json?per_page=100';
$.ajax({
type: 'GET',
url: articlesUrl,
success: function(data) {
data.articles.forEach(function(article) {
if (article.promoted == true) {
$('.promotedList').append('<li class="promotedName">' + article.name + '</li>');
}
})
},
error: function() {
console.log("Error: articlesUrl");
}
});
});
I assume that your ajax calls are setup the way you need them. Just focus on storing the section id and binding the click function the correct way.

Transformation on POST with a url encoded JSON payload

Okay, I'm not getting this one right off so we'll see if I'm missing the obvious.
Given the request
curl "https://api.me.com/v1/visitors" --data "visitor=%7B%0A++%22funnels%22%3A+%7B%7D%2C%0A++%22_partition%22%3A+96%2C%0A++%22metric_sets%22%3A+%7B%0A++++%2234%22%3A+%7B%0A++++++%22safari%22%3A+1%0A++++%7D%0A++%7D%2C%0A++%22flags%22%3A+%7B%0A++++%22Book+Pack+Purchaser%22%3A+false%2C%0A++++%22Boat+PP+Viewer%22%3A+true%2C%0A++++%22Boat+Purchaser%22%3A+false%2C%0A++++%22Mobile+Shopper%22%3A+true%2C%0A++++%22Visitor+Buy%22%3A+false%2C%0A++++%22Testing%22%3A+true%2C%0A++++%22Book+Pack+PP+Viewer%22%3A+false%2C%0A++++%22Women%27s+Dept+Visitors%22%3A+true%2C%0A++++%22Boat+Abandoner%22%3A+false%0A++%7D%2C%0A++%22replaces%22%3A+%5B%5D%2C%0A++%22shard_token%22%3A+21000096%0A%7D"
You'll notice that the --data passed is a JSON object that has been encoded.
{"not":"my design"}
You could go here to encode it: http://www.url-encode-decode.com/ basically it turns into:
{
"funnels": {},
"_partition": 96,
"metric_sets": {
"34": {
"safari": 1
}
},
"flags": {
"Book Purchaser": false,
"Boat PP Viewer": true,
"Boat Purchaser": false,
"Mobile Shopper": true,
"Visitor Buy": false,
"Testing": true,
"Book Pack PP Viewer": false,
"Women's Dept Visitors": true,
"Boat Abandoner": false
},
"replaces": [],
"shard_token": 21000096
}
Well I can't figure out how to get the value into a JSON object in a Script so I can start mashing up the data. I got a...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="Script-ProcessRequestVars">
<DisplayName>Script-ProcessRequestVars</DisplayName>
<FaultRules/>
<Properties/>
<ResourceURL>jsc://Script-ProcessRequestVars.js</ResourceURL>
</Javascript>
With a...
var processRequestPayload = function(){
context.setVariable("my.requestVerb",context.proxyRequest.method);
context.setVariable("my.visitor",context.proxyRequest.body.asForm['visitor'][0]);
var visitObj = JSON.parse(context.proxyRequest.body.asForm['visitor'][0]);
var shard = visitObj.shard_token;
};
function init() {
processRequestPayload();
}
init();
But all I get is a...
{
"fault": {
"faultstring": "Execution of Script-ProcessRequestVars failed on line 4 with error: 1",
"detail": {
"errorcode": "steps.javascript.ScriptExecutionFailedLineNumber"
}
}
}
What am I missing??
Kris, try replacing:
context.setVariable("my.visitor", context.proxyRequest.body.asForm['visitor'][0]);
With
context.setVariable("my.visitor", request.body.asForm['visitor'][0]);
There seems to be an issue with context.proxyRequest.body. If this issue gets fixed with above workaround, please open a ticket and in the meantime use this workaround.
I'm not sure why you're passing your JSON as a form parameter... Personally I would send the body as Content-Type: application/json and use the JSON Path in an ExtractVariables policy to set Apigee variables for the JSON you want to manipulate:
POST
Content-type: application/json
{
"funnels": {},
"_partition": 96,
"metric_sets": {
"34": {
"safari": 1
}
},
"flags": {
"Book Purchaser": false,
"Boat PP Viewer": true,
"Boat Purchaser": false,
"Mobile Shopper": true,
"Visitor Buy": false,
"Testing": true,
"Book Pack PP Viewer": false,
"Women's Dept Visitors": true,
"Boat Abandoner": false
},
"replaces": [],
"shard_token": 21000096
}
ExtractVariables example:
<ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Variables-1">
<DisplayName>Extract Variables 1</DisplayName>
<FaultRules/>
<JSONPayload>
<Variable name="name">
<JSONPath>$.flags.Book%20Purchaser</JSONPath>
</Variable>
</JSONPayload>
<Source clearPayload="false">request</Source>
<VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>
BTW -- you might also want to avoid putting spaces in your JSON labels -- not really standard and can cause parsing problems...
ExtractVariables http://apigee.com/docs/api-services/content/extract-message-content-using-extractvariables

Knockout.js mapping ignore

We're working with knockout.js and knockout.mapping.js on .NET MVC 4. Let's say I have such JSON:
{
"deliveryPointType": "0",
"deliveryPointTypes": [
{
"id": 0,
"text": "Pridėti rankiniu būdu"
},
{
"id": 1,
"text": "Siųsti visiems regiono objektams"
}
],
"showRegionSelection": false,
"showDeliveryPointSelection": true,
"regionId": "",
"userHasRegions": "False",
"propertyNames": {
"deliveryPointTypeName": "Pridėti rankiniu būdu"
},
"initialMaterials": [
{
"quantity": 0,
"materialTypeId": "",
"propertyNames": {},
"validMaterial": true,
"showMaterialError": false,
"materialTypeAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Material/MaterialTypeNameLookup"
}
}
],
"deliveryBuildings": [
{
"clientId": "1",
"buildingId": "1",
"regionId": "",
"newBuilding": false,
"validClient": true,
"validBuilding": true,
"validRegion": true,
"showClientError": false,
"showBuildingError": false,
"showRegionError": false,
"propertyNames": {
"clientName": "klientas",
"buildingName": "ASD project, Antagynės gatvė, Kaunas, Lietuvos Respublika"
},
"clientAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Task/PayerLookup"
},
"buildingAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/GetClientAddressListByQuery"
},
"regionAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/RegionNameLookup"
}
}
],
"hasNewBuildings": false,
"showBuildingValidation": false,
"showMinimumBuildingRequiredValidation": false,
"showMaterialValidation": false,
"validRegion": true,
"showRegionError": false,
"regionAjax": {
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/RegionNameLookup"
}
}
On form submit fail (if something goes wrong/invalid in service) it is repopulated with previous values. We convert ViewModel to JSON on form submit with $('#BuildingsJSON').val(ko.mapping.toJSON(viewModel.deliveryBuildings)).
On form repopulating, we parse JSON with ko.mapping.fromJSON(deliveryBuildings, mapping, viewModel.deliveryBuildings)(); mapping is just an empty object for now (tried "ignore" with no luck).
We use select2 fields to select addresses of buildings from a list (using ajax). Thing is, fromJSON populates almost every json property as observable, which I don't need. On select2 open we get an exception:
Uncaught TypeError: Object function observable() {
if (arguments.length > 0) {
// Write
// Ignore writes if the value hasn't changed
if (!observable['equalityComparer'] || !observable['equalityComparer'](_latestValue, arguments[0])) {
observable.valueWillMutate();
_latestValue = arguments[0];
if (DEBUG) observable._latestValue = _latestValue;
observable.valueHasMutated();
}
return this; // Permits chained assignments
}
else {
// Read
ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read"
operation
return _latestValue;
}
} has no method 'toUpperCase'
I've debugged where it breaks - on type property of ajax call. I figured that we need to exclude ajax properties from casting to observable.
So, the question is: how can one not cast specific properties of specific objects to observable()? Is it enough using mapping plugin, is additional plugin needed or is it even impossible?
Have you looked at using the copy keyword in your mapping binding? This just copies the value over into a js property rather than making it an observable.
From the documentation:
var mapping = {
'copy': ["propertyToCopy"]
}
ko.mapping.fromJS(data, mapping, viewModel);

Categories