How should I parse an array of objects in Node.js? - html

According to my research, that the best way to pass an Array of Objects through a POST method is by using the following name convention:
<!-- first student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">
<!-- second student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">
Body-parser setup:
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: true}));
When I typed in the post route "req.body.students", I was expecting an array of objects like this:
[ { first: Fname1, last: Lname1, age: Age1} , { first: Fname2, last: Lname2, age: Age2}
Instead, my console.log shows that I got this:
[ { first : [Fname1 , Fname2], last : [Lname1, Lname2], age : [Age1, Age2] } ]
What is going wrong with it? Cheers!

This is simply how the qa library handles data in the format.
It isn't how I would expect the library to behave, and it is different to how PHP (the obvious inspiration) handles data. So you might consider this a bug and join in the discussion on this issue.
You can work around the issue by using explicit indexes for your rows:
<!-- first student -->
<input type="text" name="students[0][first]">
<input type="text" name="students[0][last]">
<input type="text" name="students[0][age]">
<!-- second student -->
<input type="text" name="students[1][first]">
<input type="text" name="students[1][last]">
<input type="text" name="students[1][age]">
A test case:
var qs = require("qs");
var data = "students[0][name]=alice&students[0][age]=11&students[1][name]=bob&students[1][age]=12";
console.log(qs.parse(data));
Outputs:
{ students: [ { name: 'alice', age: '11' }, { name: 'bob', age: '12' } ] }

Related

Passing interpolation value through ngModel

<input [(ngModel)]="newVariablesAttribute.Steps"
class="form-control"
type="text" readonly
name="{{newVariablesAttribute.Steps}}">
{{stepname}}
I want to pass stepname (which I am able to show in the frontend using interpolation) using ngModel.
But It is not working.
Didn't find any issue with your code. Steps might be undefined
Component
export class SomeComponent {
newVariablesAttribute = {
Steps: 'step'
};
stepname = 'abc';
}
html:
<input [(ngModel)]="newVariablesAttribute.Steps" class="form-control" type="text" readonly name="{{newVariablesAttribute.Steps}}">{{stepname}}
O/P
Since stepname is getting rendered in the UI, you can pass it to the ngModel directly like this right -
<input [(ngModel)]="stepname"
class="form-control"
type="text" readonly
name="{{newVariablesAttribute.Steps}}">
{{stepname}}
(I guess newVariablesAttribute.Steps are some array of objects. )

Node.js body-parser won't parse input names with square brackets in json

I have a problem with Express body-parser in Node.js
I have inputs like this:
<input id="personEmail1" type="email" name="person[0][email]" placeholder="Email1" class="form-control">
<input id="personEmail2" type="email" name="person[1][email]" placeholder="Email2" class="form-control">
After when I submit my form I got this in my console.log:
{ 'person[0][email]': 'info#sss.sss', 'person[1][email]': 'info#ggg.ggg' }
But I want it to be parsed in json format:
{ person: [{email: 'info#sss.sss'}, {email: 'info#ggg.ggg'}] }
What I'm doing wrong?
for express version 4.x when you need to manually install body-parser and multer, and you want to get nested properties from the post, e.g. data[test] in the form of req.body.data.test, you need to set:
app.use(bodyParser.urlencoded({ extended: true }));
Even though you've used valid Javascript syntax for your keys, they are still just strings and no JSON parser will attempt to call eval on them.
However, JSON already has a concept of arrays, which should work in the way you are expecting them to.
It would be useful to show us the code in which the call to console.log happens. But I would guess that instead, you need to rethink the naming convention for your field names.
<input id="personEmail1" type="email" name="personEmail1" placeholder="Email1" class="form-control">
<input id="personEmail2" type="email" name="personEmail2" placeholder="Email2" class="form-control">
Then create the Javascript object from that data.
function handler(req, res) {
var people = [
{ email: req.body.personEmail1 },
{ email: req.body.personEmail2 }
];
console.log(people[0]); // person 1
console.log(people[1]); // person 2
console.log(people); // both people
}
You are using the Express body-parser middleware bracket notation correctly. But, as an example of what can be done...
Using this view:
<form method="post">
<label for="person_email_1">Email address 1</label>
<input id="person_email_1" name="person[0][email]" type="email" value="email1#example.com"> <br>
<label for="person_email_2">Email address 2</label>
<input id="person_email_2" name="person[1][email]" type="email" value="email2#example.com"> <br>
<button type="submit">Submit v1</button>
</form>
<br>
<form method="post">
<label for="person_email_1">Email address 1</label>
<input id="person_email_1" name="person[email][0]" type="email" value="email1#example.com"> <br>
<label for="person_email_2">Email address 2</label>
<input id="person_email_2" name="person[email][1]" type="email" value="email2#example.com"> <br>
<button type="submit">Submit v2a</button>
</form>
<br>
<form method="post">
<label for="person_email_1">Email address 1</label>
<input id="person_email_1" name="person[email]" type="email" value="email1#example.com"> <br>
<label for="person_email_2">Email address 2</label>
<input id="person_email_2" name="person[email]" type="email" value="email2#example.com"> <br>
<button type="submit">Submit v2b</button>
</form>
<br>
<form method="post">
<label for="person_email_1_address">Email address 1</label>
<input id="person_email_1_address" name="person[emailAddresses][0][address]" type="email" value="email1#example.com">
<input id="person_email_1_description" name="person[emailAddresses][0][description]" type="text" value="lorem ipsum 1"> <br>
<label for="person_email_2_address">Email address 2</label>
<input id="person_email_2_address" name="person[emailAddresses][1][address]" type="email" value="email2#example.com">
<input id="person_email_2_description" name="person[emailAddresses][1][description]" type="text" value="lorem ipsum 2"> <br>
<button type="submit">Submit v3</button>
</form>
...and this post handler:
function postHandler(req, res) {
console.log(JSON.stringify(req.body)); // show in console
res.send(req.body); // show in browser
}
Version 1 (your version, which works for me, and returns your desired result) req.body:
{
"person": [
{"email": "email1#example.com"},
{"email": "email2#example.com"}
]
}
Versions 2a & 2b (an array of strings, with/without index number) req.body:
{
"person": {
"email": [
"email1#example.com",
"email2#example.com"
]
}
}
Version 3 (an array of objects) req.body:
{
"person": {
"emailAddresses": [
{
"address": "email1#example.com",
"description": "lorem ipsum 1"
},
{
"address": "email2#example.com",
"description": "lorem ipsum 2"
}
]
}
}
I've personally used versions 2 & 3 on a node/Express/jquery/Bootstrap line of business app where a person or business account can have unlimited telephone numbers, email addresses, and URLs. The body-parser bracket notation made it stupid easy.
I used this https://github.com/macek/jquery-serialize-object to serialize my form as JSON. It parses data as I want and it's easy to use.
$.ajax({
type: 'post',
data: $form.serializeJSON(),
contentType: 'application/json',
url: $url,
success: function (result) { ... }
});
I think this is the easyest

output all members of a form (form.FormController)

Please see the code here
it is an angular form, and the variable form should be of FormController . As you see with the usage of form.$pristine, the variable $pristine exists in form, but why it doesn't output when I just try <pre>form = {{form}}</pre>. I wanted to see all the members (if possible function names, else at least all primitives like $dirty, $valid , etc.) Why it is not outputting in the pre tag and how can I show them? It is mainly for debugging, but curious as well.
<form novalidate name="form" class="simple-form">
Name: <input type="text" ng-model="user.name" /><br />
E-mail: <input type="email" ng-model="user.email" /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
</form>
<pre>pristine = {{form.$pristine}}</pre>
<pre>form = {{form}}</pre>
output
pristine = true
form = {}
An expression like this: {{form}} will convert the form object to a string. Angular uses the build in angular.toJson function to serialize the object. Please have a look at the documentation: angular.toJson. As you can see there all properties with a leading $ are stripped.
How to solve your problem:
You may use the JSON.stringify function to get all properties. Because you can't call this function in an expression you need to provide a helper function in your controller:
$scope.stringify = function(obj){
return JSON.stringify(obj);
}
Now you are able to output your complete form object in the view:
{{stringify(form)}}
The following should also work...
<pre>form = {{form | json}}</pre>

Create a dictionary with a HTML-form in Django

Is there any possible method to create a form with one or more elements like:
<form action="{% url "foo" %}" method="POST">
<div id="report_item">
<input type="text" name="dontknow">
<input type="date" name="dontknow">
</div>
<div id="report_item">
<input type="text" name="dontknow">
<input type="date" name="dontknow">
</div>
</form>
And to get a dictionary from this form as below:
{data:
{1: {
text: 'bla', date: '2014-03-02'
},
{2: {
text: 'second text', date: '2014-03-01'
}
}
Not quite, but you probably want to look at formsets. That gives you a series of repeated forms, which you can output on the template by just iterating through. Once you've validated the POST data if you really need a dictionary you can do something like:
data = {i: form.cleaned_data for i, form in enumerate(formset.forms)}

How to access and display mapped data with ko.mapping script (Razor page)?

Java script (getting data using Can`t get json object to with knockout answer {1} method):
<script type="text/javascript">
$.getJSON("/api/TelemarketingApi", function (result) {
function viewModel() {
return ko.mapping.fromJS(result);
};
ko.applyBindings(new viewModel());
})
.error(function () { alert("error"); });
</script>
JSON object:
[
{
"TelemCalls": [ {"ID": 1, "duratio": "11"}],
"ID": 1,
"FirstName": "Jonas",
"LastName": "Jonaitis",
"Phone": "860123123",
"Municipality": null
}
]
How can I access and display mapped JSON data in a razor page?
Do you have the viewModel mapped from the json object and binded to entire razor view.
To display values in the razor view only has to create html elements bound to the viewModel like this:
<input type="text" data-bind="value: ID" />
<input type="text" data-bind="value: FirstName" />
<input type="text" data-bind="value: LastName" />
<input type="text" data-bind="value: Phone" />
<input type="text" data-bind="value: Municipality" />
Example in Fiddle: http://jsfiddle.net/vfportero/hcVmZ/
Remember that your mapped data is accessible only in JavaScript, not on the server side while page is being built by Razor. So to show viewModel's property values on the page try the following:
<input data-bind="value: FirstName" />
<ul data-bind="foreach: TelemCalls">
<li data-bind="text: duratio"></li>
</ul>
If your top-level viewmodel is an array so use the following syntax:
<div data-bind="$data">
<input data-bind="value: FirstName" />
<ul data-bind="foreach: TelemCalls">
<li data-bind="text: duratio"></li>
</ul>
</div>