How to iterate on form array member in c# server (client is Extjs form) - forms

In the server I get my arrays as such string:
0:val1,1:val2,2:val3
I work with NameValueCollection but this iterates through all the form members.
How do I parse\iterate through array form member to get a neat array of
{"val1","val2","val3"} without its index?
BTW - the client was sent with ExtJs Form submit...(maybe its something in the client?)

I don't know how useful such an array could be if you can't map the value to its property, but try this:
var values[];
Ext.each(form.getForm().items, function (field) {
values.push(field.getValue());
}, this);
Ext.Ajax.request({
url: 'backend.php',
method: 'POST',
params: {
values: Ext.JSON.encode(values)
},
success: function(response){
// process server response here
}
});

Related

How to rename axios FormData array when submitting

Is there something I can do to prevent axios from renaming my FormData field name when it is an array.
For example:
I have an array of images I am posting using the field name of images. When I post this, I notice in the payload of my browser the field becomes multiple fields, i.e. it becomes images.0 and images.1.
In other words it looks like axios is renaming the field and making multiple fields with names like images.N.
Is there any way to avoid this renaming? On the server side I am using node with Nestjs and multer.
My Nestjs controller function expects a field name images but it throws an "unexpected field" error because axios renames the fields to images.0 and then images.1.
NestJS controller function that fails (note the field name):
#Post()
#UseGuards(AuthGuard('jwt'))
#UseInterceptors(FilesInterceptor('images', 30, { dest: './uploads' }))
create(
#Body() body: CreateAssetDto,
#User() user: RequestUser,
#UploadedFiles() files: Array<Express.Multer.File>,
) {
console.log(files, body, user.userId);
//return this.assetsService.create(body, user.userId);
}
NestJs controller function that works (note the use of the field name images.0):
#Post()
#UseGuards(AuthGuard('jwt'))
#UseInterceptors(FilesInterceptor('images.0', 30, { dest: './uploads' }))
create(
#Body() body: CreateAssetDto,
#User() user: RequestUser,
#UploadedFiles() files: Array<Express.Multer.File>,
) {
console.log(files, body, user.userId);
//return this.assetsService.create(body, user.userId);
}

Get all matching items using ids array form database

I can't receive list of items that matches with my array of ids.
This is PART of code in Angular component:
this.orderService.getSpecyficOrders(ids)
.subscribe(orders => { ...
Where ids is an array of
[{_id : ID },{_id : ID },{_id : ID },]
ID is "5235sd23424asd234223sf44" kind of string form MongoDB documents.
In angular service file I have imported:
Http, Headers, and import 'rxjs/add/operator/map';
Here is code in service in Angular:
getSpecyficOrders(ids){
return this.http.get('/api/ordersspecyfic', ids)
.map(res => res.json());
}
In express file I have require: multer, express,router,mongojs, db
And here is part of code in express, call to mongodb:
router.get('/ordersspecyfic', function(req, res, next){
var ids = req.body;
ids = ids.map(function (obj){ return mongojs.ObjectId(obj._id)});
db.orders.find({_id: {$in: ids}}, function(err, orders){
if(err){
res.send(err);
}
res.json(orders);
});
});
And I'm getting error:
Uncaught Response {_body: "TypeError: ids.map is not a function
&n…/node_modules/express/lib/router/index.js:46:12)↵", status:
500, ok: false, statusText: "Internal Server Error", headers:
Headers…}
Console.log in express file
is showing me that req.body is an empty object {}
As far as I know req.body is not an array, but I don't know if this is only problem with that code.
All others request of get single element, get all items etc. are working fine.
I just can't get this one working..
I assume you are trying to send ids to your server side with
return this.http.get('/api/ordersspecyfic', ids)
but http.get api doesn't work like that
get(url: string, options?: RequestOptionsArgs) : Observable
In order to send this data to your back-end you should use the post api
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post('/api/ordersspecyfic', ids, options)
post(url: string, body: any, options?: RequestOptionsArgs) : Observable
Source:https://angular.io/docs/ts/latest/api/http/index/Http-class.html
Two errors, backend and frontend.
Frontend error
You say this.http.get('/api/ordersspecific', ids);. This does nothing - or specifically, this only tries to get /api/ordersspecific. It doesn't send ids, your second parameter doesn't match any RequestOptions. In other words, your ids are ignored.
You'd want to append this as a query string. Check here how to add querystring parameters. But in short, it'd be something simple like:
return this.http.get('/api/ordersspecyfic?ids=<id1>&ids=<id2>...'
Backend error
You're reading stuff from body. It's a GET request, there should be no body. Read this from querystring:
router.get('/ordersspecyfic', function(req, res, next){
var ids = req.query.ids;
});

Store contents with rest proxy giving incorrect count

ExtJS 5.1.x, with several stores using rest proxy.
Here is an example:
Ext.define('cardioCatalogQT.store.TestResults', {
extend: 'Ext.data.Store',
alias: 'store.TestResults',
config:{
fields: [
{name: 'attribute', type: 'string'},
{name: 'sid', type: 'string'},
{name: 'value_s', type: 'string'},
{name: 'value_d', type: 'string'}
],
model: 'cardioCatalogQT.model.TestResult',
storeId: 'TestResults',
autoLoad: true,
pageSize: undefined,
proxy: {
url: 'http://127.0.0.1:5000/remote_results_get',
type: 'rest',
reader: {
type: 'json',
rootProperty: 'results'
}
}
}
});
This store gets populated when certain things happen in the API. After the store is populated, I need to do some basic things, like count the number of distinct instances of an attribute, say sid, which I do as follows:
test_store = Ext.getStore('TestResults');
n = test_store.collect('sid').length);
The problem is that I have to refresh the browser to get the correct value of 'n,' otherwise, the count is not right. I am doing a test_store.load() and indeed, the request is being sent to the server after the .load() is issued.
I am directly querying the backend database to see what data are there in the table and to get a count to compare to the value given by test_store.collect('sid').length);. The strange thing is that I am also printing out the store object in the debugger, and the expected records (when compared to the content in the database table) are displayed under data.items array, but the value given by test_store.collect('sid').length is not right.
This is all done sequentially in a success callback. I am wondering if there is some sort of asynchronous behavior giving me the inconsistent results between what is is the store and the count on the content of the store?
I tested this with another store that uses the rest proxy and it has the same behavior. On the other hand, using the localStorage proxy gives the correct count consistent with the store records/model instances.
Here is the relevant code in question, an Ajax request fires off and does its thing correctly, and hit this success callback. There really isn't very much interesting going on... the problem section is after the console.log('TEST STORE HERE'); where I get the store, print the contents of the store, load/sync then print the store (which works just fine) and then finally print the length of uniquely grouped items by the sid attribute (which is what is not working):
success: function(response) {
json = Ext.decode(response.responseText);
if(json !== null && typeof (json) !== 'undefined'){
for (i = 0, max = json.items.length; i < max; i += 1) {
if (print_all) {
records.push({
sid: json.items[i].sid,
attribute: json.items[i].attribute,
string: json.items[i].value_s,
number: json.items[i].value_d
});
}
else {
records.push({
sid: json.items[i].sid
})
}
}
//update store with data
store.add(records);
store.sync();
// only add to store if adding to search grid
if (!print_all) {
source.add({
key: payload.key,
type: payload.type,
description: payload.description,
criteria: payload.criteria,
atom: payload.atom,
n: store.collect('sid').length // get length of array for unique sids
});
source.sync();
}
console.log('TEST STORE HERE');
test_store = Ext.getStore('TestResults');
test_store.load();
test_store.sync();
console.log(test_store);
console.log(test_store.collect('sid').length)
}
// update grid store content
Ext.StoreMgr.get('Payload').load();
Ext.ComponentQuery.query('#searchGrid')[0].getStore().load();
}
For completeness, here is the data.items array output items:Array[2886]
which is equivalent count of unique items grouped by the attribute sid and finally the output of console.log(test_store.collect('sid').length), which gives the value from the PREVIOUS run of this: 3114...

Mongoose, does this model already exist in the collection

I'm using Mongoose on a Node.js server to save data into MongoDB. What I want to do is to check and see if a model object exists in the collection already.
For example heres my model:
var ApiRequest = new Schema({
route: String,
priority: String,
maxResponseAge: String,
status: String,
request: Schema.Types.Mixed,
timestamp: { type: Date, default: Date.now }
});
And here's what I would like to do:
var Request = mongoose.model('api-request', ApiRequest);
function newRequest(req, type) {
return new Request({
'route' : req.route.path,
'priority' : req.body.priority,
'maxResponseAge' : req.body.maxResponseAge,
'request' : getRequestByType(req, type)
});
}
function main(req, type, callback) {
var tempReq = newRequest(req, type);
Request.findOne(tempReq, '', function (err, foundRequest) {
// Bla bla whatever
callback(err, foundRequest);
});
}
The big issues I'm finding are that the tempReq which is a model has an _id variable and a timestamp that is going to be different from what is saved in the database. So I would like to ignore those fields and compare by everything else.
As a note my actual models have more variables than this hence the reason I don't want to use .find({ param : val, ....})..... and instead would like to use the existing model for comparison.
Any ideas? Thanks!
You need to use plain JS objects instead of Mongoose model instances as query objects (the first parameter to find).
So either:
Change newRequest to return a plain object and later pass that into a new Request() call if you need to add it to the database.
OR
In your main function turn tempReq into a query object like this:
var query = tempReq.toObject();
delete query._id;
Request.findOne(query, ...

backbone.js won't fetch data and populate the collection

I have this setup: require.js + backbone.js, that which populate the collection using fetch function of backbone
orders.js(collection)
define([
'underscore',
'backbone',
'models/item'
], function(_, Backbone, Item){
var Orders = Backbone.Collection.extend({
model: Item,
url: 'json/items',
initialize: function(){
},
});
return orders = new Orders();
});
orders.js(views)
define([
'jquery',
'underscore',
'backbone',
'collections/orders',
'models/item',
'text!templates/orders.tpl',
], function($, _, Backbone, Orders, Item, ordersTemplate){
var OrdersView = Backbone.View.extend({
model: Orders,
template: _.template(ordersTemplate),
initialize: function() {
_.bindAll(this);
Orders.fetch({ success: function() {
console.log(Orders.models)
}});
},
});
return OrdersView;
});
Orders.fetch won't populate the collection, though browser detects XHR json/items:
I already tried this solution Backbone.js + Rest. Collection is not populated after fetch() but still it won't work. Is there any way it can fetch data and populate it automatically to the collection? Or am I missing something?
PS: sorry for the brute code posting...
EDIT: success callback on fetch won't do anything but json/items just called by XHR on browser
EDIT: update code on order.js, removed the STORE param
EDIT: i appreciate if you can look on to this url http://mindanaojobs.net/backbone/ and inspect something in it, jsfiddle seems a little bit tricky
Does the XHR response contain an array of objects? If there is any kind of object wrapper like
{items: [{...}, {...}]}
then you need to implement the parse method accordingly.
Yes, I looked at your code and you need this in your Orders collection:
parse: function (response) { return response.items;}