Extjs5 model default values in ajax request - extjs5

I have a problem. I created a simple model and tried to save new value by using it through ajax request. But parameters which must be empty sends default value. You can see it by link under. The code does not specifically set the correct way bacause of what the console(f12) can be seen fallen challenge. In it I pass a value through a query-string, as well as through the payload-request (not yet invented how to get rid of it, as I understand it-payload is used by default). In general, instead of an empty carId call transfers Car-1.
https://fiddle.sencha.com/#fiddle/dsj
How do I fix this behavior and do that if we do not share any meaning, it passed empty?

You can create your custom proxy class that extends Ext.data.proxy.Ajax and then override buildRequest method to check for all create actions and to assign desired value to idProperty
Ext.define('CarProxy', {
extend: 'Ext.data.proxy.Ajax',
alias: 'proxy.carproxy',
type: 'ajax',
idParam: 'carId',
reader: {
type: 'json',
rootProperty: 'data'
},
api: {
create: './createcar.json'
},
writer: {
type: 'form'
},
buildRequest: function(operation) {
var request = this.callParent(arguments);
if (request.getAction() === 'create') {
request.getRecords().forEach(function(record) {
record.set('carId', ''); //assing desired value to id
});
}
return request;
}
});

Thanks everyone who answered. I want to show my solution:
add to model definition parameter
identifier: 'custom' .
And then create appropriate identifier which will return undefined on generate method:
Ext.define('Custom', {
extend: 'Ext.data.identifier.Generator',
alias: 'data.identifier.custom',
generate: function() {
return;
}
});

This is default ExtJS behaviour. If you do not specify id, it is generated. To avoid that you can for add constructor to your model:
Ext.define("Car", {
[...],
constructor: function() {
this.callParent(arguments);
// check if it is new record
if (this.phantom) {
// delete generated id
delete this.data[this.idProperty];
}
}
});

Related

Sequelize findOrCreate not excluding attributes defined in the exclude array

Following is the code:
Accounts.findOrCreate({
where: {
userName: request.payload.userName
},
attributes: { exclude: ['password','sessionToken'] },
defaults: request.payload
}).spread(function (account, created) {
if (created) {
var account = account.get({
plain: true
});
console.log(account); // has the password and sessionToken fields
return reply(account).code(201);
} else {
return reply("user name already exists").code(422);
}
});
I noticed that sequelize first fires a select query in which the password field is not present, then it fires an insert statement in which the password field is present, and that needs to be there.
I would just like the password and sessionToken not be present in the resulting account object. I could of course delete those properties from the object but I am looking for a more straightforward way.
It seems like you need to delete those fields manually. According to the source code, findOrCreate method first fires the findOne function and then it goes with create if instance was not found. The create method does not accept attributes parameter. In such a case all fields will be returned.
Good solution would be to create instance method in the Accounts model in order to return an instance with only the desired attributes.
{
instanceMethods: {
toJson: function() {
let account = {
id: this.get('id'),
userName: this.get('userName')
// and other fields you want to include
};
return account;
}
}
}
Then you could simply use the toJson method when returning raw representation of object:
Accounts.findOrCreate({ where: { userName: 'username' } }).spread((account, created) => {
return account ? account.toJson() : null;
});
As mentioned by piotrbienias you can follow his way otherwise just delete the unwanted elements like this:
Accounts.findOrCreate({
where: {
userName: request.payload.userName
},
defaults: request.payload
}).spread(function (account, created) {
if (created) {
var account = account.get({
plain: true
});
delete account.password;
delete account.sessionToken;
console.log(account); // now you don't have the password and sessionToken fields
return reply(account).code(201);
} else {
return reply("user name already exists").code(422);
}
});

Complicated nested json loops to store with extjs

I'm using a geojson extracted from naturalearthdata which looks like that :
All I want is to catch the NAME of each feature in order to display them in a grid (live search grid.. BTW is it efficient for 2000 names?)
But I can't access to all the name with root property. I tried to loop into all the features
Ext.define('myApp.store.Places', {
extend: 'Ext.data.Store',
alias: 'store.places',
requires : ['myApp.model.PlacesModel',
'myApp.view.main.MainModel'],
id: 'Places',
model: 'myApp.model.PlacesModel',
autoLoad: true,
proxy: {
type: 'ajax',
url : '/resources/data/coord.json',
reader: {
type: 'json',
transform: {
fn: function(data) {
for(var i = 0; i < data.features.length -1; i++){
names_places.push(data.features[i].properties.NAME);
}
debugger;
return names_places;
},
scope: this
}
}
}
});
But the debugger sent me that result which I don't understand :
Especially when the array looks good :
What is the good way to catch only the NAME? Does the return has to look to a json?
You can use the mapping attribute on the fields array in your model definition to map the correct attribute in the json to a field.
You set the rootProperty to features for the reader.
Then in your fields array something similar to this
fields: [
{ name: 'myCustomField', mapping: 'properties.NAME' }
]

ExtJs5: How to read server response in Model.save

I use Model.save to save data from the ExtJs form. Sometimes server returns operation status in following format:
{"success": false, "error": {"name": "Invalid Name"}}
The following code sends data from form to server:
var model = formPanel.getRecord();
model.save({
callback: function(record, operation, success) {
// operation.response is null,
// and success === true
// how to read server response here?
}
})
Server response is treated as successful because HTTP status is 200. So I I have to read server response to check operation status. But operation.response is null in callback function.
Here is my Model:
Ext.define('My.Model', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{name: 'id', type: 'auto'},
{name: 'name', type: 'auto'}
],
proxy: {
type: 'rest',
url: 'api/v1/models',
appendId: true,
reader: {
type: 'json',
},
writer: {
type: 'json'
}
}
});
Question: how can I access server response after Model.save's call?
More generic question: is it semantically correct to use Model.load or Model.save to populate/save the ExtJs form?
I'm using ExJs 5.0.1.1255.
I created some simple test code for this:
var Clazz = Ext.define('MyModel', {
extend: 'Ext.data.Model',
proxy: {
type: 'rest',
url: 'api/v1/models'
}
});
var instance = Ext.create('MyModel', {
name: 'MyName'
});
instance.save({
callback: function(record, operation) {
}
});
The server responds with:
{
success: true,
something: 'else'
}
You can see this in a fiddle here: https://fiddle.sencha.com/#fiddle/fhi
With this code, the callback has a record argument, and record.data contains the the original record merged with the server response. In addition, you can do operation.getResponse() (rather than just operation.response) to get full access to the server's response.
In regard to your question on load vs save, if you use view models and bind the model that way, it kind of becomes moot as your form should always reflect the state of the model.
Using model.save() and Model.load() is definitely the correct thing to do.
In addition to providing a custom callback, you should investigate configuring a custom proxy. In a custom proxy, you can provide your own implementation of the extractResponseData method. This would let you centralise your need to examine the server response.

IBM Worklight JSONStore - Add and get data

I am using worlight JSONstore. I am new to it. I tried searching that read all docs but didn't get much idea.
I have one login page from that I get some json data I want to store that data using jsonstore. and get that afterwards.
I made jsonstore adapter.
Json-Store-Impl.js
function getJsonStores(custData) {
var data = custData;
return data;
//custdata is json
}
function addJsonStore(param1) {
var input = {
method : 'put',
returnedContentType : 'json',
path : 'userInputRequired'
};
return WL.Server.invokeHttp(input);
}
function updateJsonStore(param1) {
var input = {
method : 'post',
returnedContentType : 'json',
path : 'userInputRequired'
};
return WL.Server.invokeHttp(input);
}
function deleteJsonStore(param1) {
var input = {
method : 'delete',
returnedContentType : 'json',
path : 'userInputRequired'
};
return WL.Server.invokeHttp(input);
}
after that I Create a local JSON store.
famlCollection.js
;(function () {
WL.JSONStore.init({
faml : {
searchFields: {"response.mci.txnid":"string","response.mci.scrnseqnbr":"string","response.loginUser":"string","request.fldWebServerId":"string","response.fldRsaImageHeight":"string","request.fldRequestId":"string","request.fldTxnId":"string","response.fldDeviceTokenFSO":"string","response.fldRsaCollectionRequired":"string","response.datlastsuccesslogin":"string","response.fldRsaUserPhrase":"string","response.fldRsaAuthTxnId":"string","response.rc.returncode":"string","response.datcurrentlogin":"string","response.mci.deviceid":"string","response.customername":"string","request.fldDeviceId":"string","response.fldRsaUserStatus":"string","request.fldScrnSeqNbr":"string","response.fldRsaImageWidth":"string","request.fldLangId":"string","response.fldTptCustomer":"string","response.encflag":"string","response.rc.errorcode":"string","response.fldRsaImagePath":"string","response.mci.appid":"string","response.mci.requestid":"string","response.rc.errormessage":"string","response.mci.appserverid":"string","response.fldRsaCollectionType":"string","request.fldAppId":"string","response.fldRsaImageId":"string","request.fldLoginUserId":"string","response.mci.sessionid":"string","response.mci.langid":"string","response.mci.remoteaddress":"string","request.fldAppServerId":"string","response.mci.webserverid":"string","response.fldRsaImageText":"string","response.fldRsaEnrollRequired":"string","response.fldRsaActivityFlag":"string"},
adapter : {
name: 'JsonStore',
replace: 'updateJsonStore',
remove: 'deleteJsonStore',
add: 'addJsonStore',
load: {
procedure: 'getJsonStores',
params: [],
key: 'faml'
},
accept: function (data) {
return (data.status === 200);
}
}
}
}, {
password : 'PleaseChangeThisPassword'
})
.then(function () {
WL.Logger.debug(['Take a look at the JSONStore documentation and getting started module for more details and code samples.',
'At this point there is no data inside your collection ("faml"), but JSONStore is ready to be used.',
'You can use WL.JSONStore.get("faml").load() to load data from the adapter.',
'These are some common JSONStore methods: load, add, replace, remove, count, push, find, findById, findAll.',
'Most operations are asynchronous, wait until the last operation finished before calling the next one.',
'JSONStore is currently supported for production only in Android and iOS environments.',
'Search Fields are not dynamic, call WL.JSONStore.destroy() and then initialize the collection with the new fields.'].join('\n'));
})
.fail(function (errObj) {
WL.Logger.ctx({pretty: true}).debug(errObj);
});
}());
When I clicked on login button I call getJsonStores like this -
getJsonStores = function(){
custData = responseData();
var invocationData = {
adapter : "JsonStore",
procedure : "getJsonStores",
parameters : [custData],
compressResponse : true
};
//WL.Logger.debug('invoke msg '+invocationData, '');
WL.Client.invokeProcedure(invocationData, {
onSuccess : sucess,
onFailure : AdapterFail,
timeout: timeout
});
};
I followed these steps
Is this right way? and how can I check jsonstore working locally or not? and how can I store my jsondata in JSONStore? Where should I initialize the wlCommonInit function in project?
plz Help me out.
Open main.js and find the wlCommonInit function, add the JSONStore init code.
WL.JSONStore.init(...)
You already have an adapter that returns the data you want to add to JSONStore, call it any time after init has finished.
WL.Client.invokeProcedure(...)
Inside the onSuccess callback, a function that gets executed when you successfully get data from the adapter, start using the JSONStore API. One high level way to write the code would be, if the collection is empty (the count API returns 0), then add all documents to the collection.
WL.JSONStore.get(collectionName).count()
.then(function (countResult) {
if(countResult === 0) {
//collection is empty, add data
WL.JSONStore.get(collectionName).add([{name: 'carlos'}, {name: 'mike'}])
.then(function () {
//data stored succesfully
});
}
});
Instead of adding [{name: 'carlos'}, {name: 'mike'}] you probably want to add the data returned from the adapter.
Later in your application, you can use the find API to get data back:
WL.JSONStore.get(collectionName).findAll()
.then(function (findResults) {
//...
});
There is also a find API that takes queries (e.g. {name: 'carlos'}), look at the getting started module here and the documentation here.
It's worth mentioning that the JSONStore API is asynchronous, you must wait for the callbacks in order to perform the next operation.

FineUploader OnComplete method not firing

So, I'm using FineUploader 3.3 within a MVC 4 application, and this is a very cool plugin, well worth the nominal cost. Now, I just need to get it working correctly.
I'm pretty new to MVC and absolutely new to passing back JSON, so I need some help getting this to work. Here's what I'm using, all within doc.ready.
var manualuploader = $('#files-upload').fineUploader({
request:
{
endpoint: '#Url.Action("UploadFile", "Survey")',
customHeaders: { Accept: 'application/json' },
params: {
//variables are populated outside of this code snippet
surveyInstanceId: (function () { return instance; }),
surveyItemResultId: (function () { return surveyItemResultId; }),
itemId: (function () { return itemId; }),
imageLoopCounter: (function () { return counter++; })
},
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png', 'bmp']
},
multiple: true,
text: {
uploadButton: '<i class="icon-plus icon-white"></i>Drop or Select Files'
},
callbacks: {
onComplete: function(id, fileName, responseJSON) {
alert("Success: " + responseJSON.success);
if (responseJSON.success) {
$('#files-upload').append('<img src="img/success.jpg" alt="' + fileName + '">');
}
}
}
}
EDIT: I had been using Internet Explorer 9, then switched to Chrome, Firefox and I can upload just fine. What's required for IE9? Validation doesn't work, regardless of browser.
Endpoint fires, and file/parameters are populated, so this is all good! Validation doesn't stop a user from selecting something outside of this list, but I can work with this for the time being. I can successfully save and do what I need to do with my upload, minus getting the OnComplete to fire. Actually, in IE, I get an OPEN/SAVE dialog with what I have currently.
Question: Are the function parameters in onComplete (id, filename, responseJSON) getting populated by the return or on the way out? I'm just confused about this. Does my JSON have to have these parameters in it, and populated?
I don't do this (populate those parameters), and my output method in C# returns JsonResult looking like this, just returning 'success' (if appropriate):
return Json(new { success = true });
Do I need to add more? This line is after the saving takes place, and all I want to do is tell the user all is good or not. Does the success property in my JSON match up with the responseJSON.success?
What am I missing, or have wrong?
Addressing the items in your question:
Regarding restrictions inside of the "select files" dialog, you must also set the acceptFiles validation option. See the validation option section in the readme for more details.
Your validation option property in the wrong place. It should not be under the request property/option. The same is true for your text, multiple, and callbacks options/properties. Also, you are not setting your callbacks correctly for the jQuery plug-in.
The open/save dialog in IE is caused by your server not returning a response with the correct "Content-Type" header. Your response's Content-Type should be "text/plain". See the server-side readme for more details.
Anything your server returns in it's response will be parsed by Fine Uploader using JSON.parse when handling the response client-side. The result of invoking JSON.parse on your server's response will be passed as the responseJSON parameter to your onComplete callback handler. If you want to pass specific information from your server to your client-side code, such as some text you may want to display client-side, the new name of the uploaded file, etc, you can do so by adding appropriate properties to your server response. This data will then be made available to you in your onComplete handler. If you don't have any need for this, you can simply return the "success" response you are currently returning. The server-side readme, which I have linked to, provides more information about all of this.
To clarify what I have said in #2, your code should look like this:
$('#files-upload').fineUploader({
request: {
endpoint: '#Url.Action("UploadFile", "Survey")',
customHeaders: { Accept: 'application/json' },
params: {
//variables are populated outside of this code snippet
surveyInstanceId: (function () { return instance; }),
surveyItemResultId: (function () { return surveyItemResultId; }),
itemId: (function () { return itemId; }),
imageLoopCounter: (function () { return counter++; })
}
},
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png', 'bmp']
},
text: {
uploadButton: '<i class="icon-plus icon-white"></i>Drop or Select Files'
}
})
.on('complete', function(event, id, fileName, responseJSON) {
alert("Success: " + responseJSON.success);
if (responseJSON.success) {
$('#files-upload').append('<img src="img/success.jpg" alt="' + fileName + '">');
}
});