Javascript MVC - How to retain initial values - javascript

I need to retain the original values from data returned from a model instance. It seems like there should be a method for returning the unmodified data from the model but I can't find it anywhere. I tried using backup.js but this only works for static string attributes.
$.Model('My.Example.Models.Thing',
/* #Static */
{
},
/* #Prototype */
{
getMyStuff : function(args) {
$.ajax({
url : '/path/to/my/service,
type : 'get',
contentType : 'application/json',
dataType : 'json',
success : args.success,
error : args.error,
cache : false
});
}
...
init: {
env = this;
}
show: function(){
thing = new My.Example.Models.Thing();
thing.getMyStuff({
params:params,
success: function(data){
// How do you store the original data for later,
// Without it getting updated when data is modified?
thing.myStuff = data;
env.options.thing = thing;
env.processMyStuff(thing);
},
error: function(){
console.log('error');
}
});
},

try $.extend({}, data), or $.extend(true, {}, data) for deep copy if you are using jquery > 1.1.4

Related

Persist additional dataSource.read parameters on paganation in Kendo data grid

I have a Kendo Grid that loads data via ajax with a call to server-side ASP.NET read method:
public virtual JsonResult Read(DataSourceRequest request, string anotherParam)
In my client-side JS, I trigger a read when a button is clicked:
grid.dataSource.read( { anotherParam: 'foo' });
grid.refresh();
This works as expected, only I lose the additional param when I move through the pages of results in the grid, or use the refresh icon on the grid to reload the data.
How do I persist the additional parameter data in the grid?
I have tried setting
grid.dataSource.data
directly, but without much luck. I either get an error if I pass an object, or no effect if I pass the name of a JS function that returns data.
if you want to pass additional parameters to Read ajax datasource method (server side), you may use
.DataSource(dataSource => dataSource
...
.Read(read => read.Action("Read", controllerName, new { anotherParam= "foo"}))
...
)
if you want to pass additional parameters through client scripting you may use datasource.transport.parameterMap, something as below
parameterMap: function(data, type) {
if (type == "read") {
return { request:kendo.stringify(data), anotherParam:"foo" }
}
Use the datasource.transport.parameterMap
parameterMap: function(data, type) {
if (type == "read") {
return kendo.stringify(data, anotherParam);
}
I'm not sure where your other param is coming from, but this is generally how I send extra parameters to the server.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.parameterMap
if use datasource object :
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Api/GetData',
contentType: "application/json; charset=utf-8", // optional
dataType: "json",
data: function () {
return {
additionalParam: value
};
}
},
//parameterMap: function (data, type) {
// and so use this property to send additional param
// return $.extend({ "additionalParam": value }, data);
//}
},
schema: {
type: "json",
data: function (data) {
return data.result;
},
},
pageSize: 5,
serverPaging: true,
serverSorting: true
});
and set options in grid:
$("#grid").kendoGrid({
autoBind: false,
dataSource: dataSource,
selectable: "multiple cell",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
]
});
and in click event this code :
dataSource.read();
and in api web method this action:
[HttpGet]
public HttpResponseMessage GetData([FromUri]KendoGridParams/* define class to get parameter from javascript*/ _param)
{
// use _param to filtering, paging and other actions
try
{
var result = Service.AllCustomers();
return Request.CreateResponse(HttpStatusCode.OK, new { result = result });
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, new { result = string.Empty });
}
}
good luck.
To persist the updated value of the additional parameter through pagination, you will need to create a global variable and save the value to it.
var anotherParamValue= "";//declare a global variable at the top. Can be assigned some default value as well instead of blank
Then, when you trigger the datasource read event, you should save the value to the global variable we created earlier.
anotherParamValue = 'foo';//save the new value to the global variable
grid.dataSource.read( { anotherParam: anotherParamValue });
grid.refresh();
Now, this is important. In your datasource object transport.read.data must be set to use a function as shown below:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Api/GetData',
contentType: "application/json; charset=utf-8", // optional
dataType: "json",
//Must be set to use a function, to pass dynamic values of the parameter
data: function () {
return {
additionalParam: anotherParamValue //get the value from the global variable
};
}
},
},
schema: {
type: "json",
data: function (data) {
return data.result;
},
},
pageSize: 5,
serverPaging: true,
serverSorting: true
});
Now on every page button click, you should get the updated value of the anotherParam which is currently set to foo

No data returned when modularizing API in JS

I am trying to modularize my JS code by creating an API module, where I can retrieve all required data using Liferay's AUI ajax features. Currently I have this:
var API = (function() {
var getAsistencias = function(idEdicion, periodo) {
AUI().use('aui-io-request', function(A) {
A.io.request('myapiaddress', {
method : 'post',
dataType : 'json',
data : {
_mypackage_WAR_myportlet_periodo : periodo,
idEdicion : idEdicion
},
on : {
success : function() {
data = this.get('responseData');
return data;
}
}
});
});
};
return {
getAsistencias : getAsistencias,
}
})();
However when I call it like this:
var data = API.getAsistencias(id, dataInfo);
Data is always null even though in the onSuccess method it is actually retrieving the data correctly. What am I doing wrong?
Also how can I manage errors?
The main problem here is you are not returning anything from your functions. This should be something like this
var API = (function() {
var getAsistencias = function(idEdicion, periodo,callback) {
AUI().use('aui-io-request', function(A) {
A.io.request('myapiaddress', {
method : 'post',
dataType : 'json',
data : {
_mypackage_WAR_myportlet_periodo : periodo,
idEdicion : idEdicion
},
on : {
success : function() {
data = this.get('responseData');
callback(data);
}
}
});
});
};
return {
getAsistencias:getAsistencias
};
})();
API.getAsistencias(id,periodo,function(data){
Console.log(data);
//Do something here
});

Set model from action and reload template in ember js

I have redirected from another action controller to one controller.
this.get('controllers.searchResult').send('searchDoc', query);
Here I obtain array object using AJAX request
App.SearchResultController = Ember.ArrayController.extend({
serverURL: 'someURL',
actions: {
searchDoc: function(query) {
$.ajax({
type: "GET",
url: serverURL + request,
data : 'q=' + query,
dataType : "JSON",
context : this, // to increase the scope of
statusCode : {
200 : function(response) {
var docs = [];
response.docs.forEach(function(doc) {
docs.push(App.Doc.create(doc));
});
// do something here so that
// docs get save in the model
// and result page get reload
},
400 : function() {
console.log('status 400 something went wrong');
}
}
});
}
}
});
I am new for Ember JS. I am willing to store/save/add this docs object in the model and reload my route searchResult.
You should keep a reference to the controller and use it to set the content when you get the results back.
Example:
App.SearchResultController = Ember.ArrayController.extend({
serverURL: 'someURL',
actions: {
searchDoc: function(query) {
var self = this; // keep a reference to the controller
$.ajax({
type: "GET",
url: serverURL + request,
data : 'q=' + query,
dataType : "JSON",
statusCode : {
200 : function(response) {
var docs = Ember.A();
response.docs.forEach(function(doc) {
docs.pushObject(App.Doc.create(doc));
});
self.set('content', docs); // use the controller reference to set the content
},
400 : function() {
console.log('status 400 something went wrong');
}
}
});
}
}
});
I also added the usage of an Ember array in the example.
Setting the content should trigger an update of your view.
You can transition to searchResult using the following:
this.get('controllers.searchResult').send('searchDoc', query);
this.transitionToRoute('searchResult');

Backbone.js Unable to parse response from collectio.toJSON()

I am learning Backbone and it would be great if someone can help me with this issue. After I do a fetch on my collection, in success callback I get the parsed data using collection.toJSON(), this actually returns an object and I am unable to get anything out of this object. This object actually has data that I need.
My question is how do I access rows property in my object. Here is my code for your reference
var testCollection = Backbone.Collection.extend({
model:myModel,
url: '/myApiEndPoint',
data: '',
initialize: function(models, options) {
this.data = models.data;
},
fetch: function(options) {
var ajaxConfig = {
url: this.url,
data: this.data,
type: 'POST',
dataType: 'text',
contentType: 'text/xml',
parse: true
};
options = _.extend({}, ajaxConfig, options);
return Backbone.Collection.prototype.fetch.call(this, options);
},
parse: function(xmlResponse) {
// I have some parsing logic to extract uid and rows from my xmlResponse
return {
uid: uid,
rows: rows
};
},
});
var collObj = new testCollection({data: xmlQuery1});
collObj.fetch({
success: function(collection){
// This code block will be triggered only after receiving the data.
console.log(collection.toJSON());
}
});
As the name toJSON suggests, it returns you the array of JSON objects where each object is a Model's JSON object. You can fetch the required properties in this way:
collObj.fetch({
success: function(collection){
// This code block will be triggered only after receiving the data.
console.log(collection.toJSON());
var uid = 'uid-of-an-object-to-access';
var rows = collection.get(uid).get('rows');
console.log(rows);
}
});

Cannot copy object property in javascript

I have an ajax call which gathers the parent and child dependencies for some entities. Inside the success function I assign what ajax returns (data) to a global level object.
$.ajax(
{
type: "POST",
url: 'ajax_handler.php',
data: {action:'get_dependencies', relation:relation, 'jobs[]':jobs, project:project},
dataType: 'json',
async: false, //do not change
success: function(data)
{
for(var key in data)
{
if( data.hasOwnProperty(key) )
{
//Copy data object to document level existingDependency object
existingDependency[key] = data[key];
}
}
},
error: function(xhr)
{
alert('error2:'+xhr.responseText);
}
});
I call this AJAX which is in a function twice. One for parents and one for children. I figured that this line existingDependency[key] = data[key]; is reassigning the object thus the previous assignment is lost. In other words the existingDependency object cannot hold both ['parent'] and ['child'] properties together.
To fix this I did the below changes so that existingDependency holds both properties:
success: function(data)
{
for(var key in data)
{
if( data[key].hasOwnProperty(relation) )
{
//Copy data object to document level existingDependency object
existingDependency[key][relation] = data[key][relation];
}
}
}
But this does not work at all. existingDependency object is empty. Below alerts empty.
var keys = '';
for(key in existingDependency)
{
keys += key+'\n';
}
alert(keys);
Any ideas why this assignment existingDependency[key][relation] = data[key][relation] does not work? data[key][relation] holds an array if it makes any difference.
Use extend:
$.ajax({
type: "POST",
url: 'ajax_handler.php',
data: {
action:'get_dependencies',
relation:relation,
'jobs[]':jobs,
project:project
},
dataType: 'json',
async: false, //do not change
success: function(data) {
$.extend(true, existingDependency, data);//this will copy/merge "data" into "existingDependency". properties from "data" that also exist in "existingDependency" will be overwritten with those from "data".
},
error: function(xhr) {
alert('error2:'+xhr.responseText);
}
});
As for why eD[key] = data[key] works while eD[key][relation] = data[key][relation] does not its hard to say without being able to run your code and debug it. But if eD[key] did not yet exist yet then it would not be able to add "relation" to it. A possible fix for that would have been:
if (!eD.hasOwnProperty(key)){
eD[key] = {};
}
eD[key][relation] = data[key][relation];

Categories