Passing parameter in javascript function is giving error - javascript

I am using extjs grid , and i put a render function on a coloumn of a grid
/**
* function for rendering the link
**/
function linkRenderer(data, cell, record, rowIndex, columnIndex, store) {
console.log(record.id);
if (data != null) {
return '' + data + '';
}
return data;
}
while on clicking the link i got an error that whatever the value of record.id is not not defined
Please suggest what solution i can do .

Do you have a idProperty set for your store? set the idProperty to one of the values used to identify unique records. This will ensure that record.id is set to a value. For accessing all other values of the record, you will have to access them through record.data.proerty
Update: You need to use escape characters so that the string values are properly passed to the resellerwindow method:
+ data + ''

But that's pretty clear the value of record.id is not define. Dah!

If the output of your console log is a string you are calling your function wrong, you are missing some quotes if record.id is a string.
function linkRenderer(data, cell, record, rowIndex, columnIndex, store) {
if (data != null) {
return String.format('{1}', record.id, data);
}
return data;
}

Related

Set default notNullable reference column in Knex migration only for existing rows

I have a postgresql database, and I am trying the following migration to add a non-nullable reference column to an existing table, using Knex:
exports.up = function (knex) {
return knex.schema.table('Donation', (table) => {
table.integer('causeId').notNullable();
table.foreign('causeId').references('Cause.id');
});
};
When I run this migration, I get the following error due to existing rows:
error: alter table "Donation" add column "causeId" integer not null - column "causeId" contains null values
I want to seed the column with a default value only for existing rows. For subsequent insertions, I would rather the insert fail if a value is not provided, so .notNullable().defaultTo(...) won't work.
I was thinking of maybe using defaultTo() only for the initial migration and then removing the constraint after, but I'm drawing a blank on how to accomplish this.
Any help would be appreciated!
My solution ended up being to use defaultTo(...) on creation of this column and then alter it afterwards using alterTable(...).
Not sure of a better way, but this works.
exports.up = function (knex) {
function relateCauseToDonation() {
return knex.schema.table('Donation', (table) => {
table.integer('causeId').notNullable().defaultTo(1);
table.foreign('causeId').references('Cause.id');
});
}
function removeDefaultToFromCauseId() {
return knex.schema.alterTable('Donation', (table) => {
table.integer('causeId').notNullable().alter();
});
}
return relateCauseToDonation().then(removeDefaultToFromCauseId);
};

Is there another way to set initial values on a Kendo virtualized mutliselect widget?

I have a kendo multi-select widget that is bound to a lot of data, to handle this I have virtualized the widget and put the stress onto the server.
I'm trying to select some initial data via a javascript function that passes an array of Ids. It works well only if the data that's being selected is on the first paged result set of the widget, if any of the Ids are further in then they are not selected and I need to fix it.
Here is the code for my widget:
#(Html.Kendo().MultiSelect()
.Name("Cars")
.DataTextField("Name")
.DataValueField("Id")
.Placeholder("Select cars...")
.Filter(FilterType.Contains)
.DataSource(source => { source
.Custom()
.ServerFiltering(true)
.Events(e => e.Error("errorHandler"))
.ServerPaging(true)
.PageSize(80)
.Type("aspnetmvc-ajax")
.Transport(transport => {
transport.Read("GetData", "Positions");
})
.Schema(schema => { schema
.Data("Data")
.Total("Total")
.Errors("Errors");
});
}))
The data is received from the GetData Method of the Positions controller which is tied to my cars repository.
GetData
public JsonResult GetData([DataSourceRequest] DataSourceRequest request)
{
var car = unitOfWork.CarRepository.Get().OrderBy(n => n.Name);
var results = vessel.ToDataSourceResult(request);
return Json(results);
}
Here is my function that runs after user input (button). I've added a sample array to show you what's passed in.
InitialSelection
function initialSelection(filter) {
//filter is: "6544","4880","6545","6548"
var carSelection = $("#Cars").data("kendoMultiSelect");
var filterArray = filter.split(',').map(Number);
if (filterArray.length > 0) {
console.log(filterArray)
carSelection.value(filterArray);
} else {
carSelection.value();
}
}
Is there a better way to make an initial selection of data than what I'm doing with the above javascript? As I said, if the ids are not on the first page of results that are returned, they are not selected which is frustrating.
You could simply change the read declaration to something like this:
.Transport(transport => {
transport.Read(read => read.Action("GetData", "Positions").Data("intialvalues"));
})
Then add a function for the initialvalues data object like:
function inititalvalues(){
var filterArray = filter.split(',').map(Number);
if(filterArray === undefined || filterArray === null || filterArray.length <= 0)
{
filterArray = []
}
return {filterValues: filterArray};
}
then in your read method on your controller you add the following:
public JsonResult GetData([DataSourceRequest] DataSourceRequest request, List<int> filterValues)
{
if (filterValues.Count > 0 && request.Page == 1)
{
..get the first page minus how many filterValues you have to inject the selected Items at the top of the list...
}
else if (filterValues.Count > 0 && request.Page > 1)
{
..get the page you need and remove any selected items from the page as they will be at the top...
}
else
{
..just get everything as normal as nothing should be selected at this stage.
}
return your paged resultset back...
}
hopefully that gives you a starting point.

Inserting into SQLite database with parameters

I am building a cross-platform app using AngularJS, Monaca and OnsenUI.
I have implemented a SQLite database to save data to be able to work offline. My implementation is based on the answer found HERE
I have a view where the user can select any number of options and those option values should then be saved to the SQLite database. Each option value can be saved to the same database table or separate tables - depending on the option value selected.
With this I am trying to refactor my insert statement to make it more efficient as it may be called many times. In my app.js controller I have a function that checks which option value was selected in the view, and then calls the goInsert() function that inserts the selected option value into the SQLite Database. Below is a sample of my function.
$scope.selectedIDOne = ""; // Variable to hold selected options value
$scope.changedValue = function (item, identifier) // item = selected option value; identifier = identifies table name to insert into
{
switch (identifier)
{
case "Square":
$scope.selectedIDOne = item;
db.transaction(goInsert(identifier), errorCB, successCB); // Error on refactored goInsert(identifier) function trying to pass identifier
break;
default:
// TODO
}
}
Then I try the following in my goInsert() function.
function goInsert(identifier) // Error here
{
switch (identifier)
{
case "Square":
db.transaction(insertSquareDB, errorCB, successCB);
break;
}
}
function insertSquareDB(tx)
{
tx.executeSql('INSERT OR IGNORE INTO tb_square (square_id) VALUES ("' + $scope.selectedIDOne + '" )');
}
When I run the code I get an error where indicated but the value is nonetheless inserted int the database. The error is thrown at the goInsert(identifier) function call. The error is:
TypeError: Failed to execute 'Transaction' on 'Database'. The callback provided as parameter 1 is not a function.
How can I implement this solution please? Or is there a better way? I would also ideally not like to create multiple insertSquareDB(tx) functions e.g. insertCircleDB(tx), insertROundDB(tx) etc. Is there a way I can have 1 function defined that inserts values dynamically e.g. (hypothetical)
function insertSquareDB(tx, tableName, columnName, optionValues)
{
tx.executeSql('INSERT OR IGNORE INTO tableName (columnName) VALUES ("' + optionValues + '" )');
}
You don't need to wrap your goInsert(identifier) call inside a transaction:
switch (identifier)
{
case "Square":
$scope.selectedIDOne = item;
goInsert(identifier);
...
}
If you want to be able to call one function to insert any shape into the database, your best bet is to dynamically generate the SQL statement:
function insertShapeDB(shape, value)
{
var tableName = '';
var columnName = '';
if (shape === 'Square') {
tableName = 'tb_square';
columnName = 'square_id';
}
else if (shape === 'Circle') {
tableName = 'tb_circle';
columnName = 'circle_id';
}
else if (shape === 'Round') {
tableName = 'tb_round';
columnName = 'round_id';
}
var sql = 'INSERT OR IGNORE INTO ' + tableName + ' (' + columnName + ') VALUES (?)';
db.transaction(function(tx) {
tx.executeSql(sql, [value]);
});
}

Calling api client to modify the data of parent api client call

client.post(config.apiUrl+"cart", args, function(data,response) {
if (data.status == 'success') {
for (var key in data.data.cart_items_list) {
if (data.data.cart_items_list.hasOwnProperty(key)) {
data.data.cart_items_list[key].child.prodqty = function () {
client.get(config.apiUrl+"product/"+data.data.cart_items_list[key].child.child_id+"/quantity", function(invdata, invresponse) {
if(invdata.status == 'success'){
console.log(invdata.data);
return invdata.data;
console.log(data.data.cart_items_list[key].child.prodqty);
}
})
}
}
}
console.log(data.data.cart_items_list);
}
})
Above is piece of code I have written to get one modify the data I got from api client call.
The first api call will a json data. I am looping thru that data to get one value from another api and append to parent's json data
console.log(data.data.cart_items_list[key].child.prodqty); line prints the correct value in my logs, but console.log(data.data.cart_items_list); this is not having the newly(child.prodqty) appended value in it.
I am very much new in Node.js so I don't know whether I am doing it correct
EDIT:
if I console.log(data.data.cart_items_list); the output has prodqty in it. but its coming like this. prodqty: [Function]
For default you say that data.data.cart_items_list get prodqty: [Function]. If you get the prodqty value you need to set this value in data.data.cart_items_list, thus you can catch it after the loop. I my opinion, I prefer to create a new var when I set it:
client.post(config.apiUrl+"cart", args, function(data,response) {
var prodqty = {};
if (data.status == 'success') {
for (var key in data.data.cart_items_list) {
if (data.data.cart_items_list.hasOwnProperty(key)) {
data.data.cart_items_list[key].child.prodqty = function () {
client.get(config.apiUrl+"product/"+data.data.cart_items_list[key].child.child_id+"/quantity", function(invdata, invresponse) {
if(invdata.status == 'success'){
console.log(invdata.data);
return invdata.data;
prodqty.key = data.data.cart_items_list[key].child.prodqty; //prodqty associated with his key
console.log(data.data.cart_items_list[key].child.prodqty);
}
})
}
}
}
console.log(JSON.stringify(prodqty));
console.log(data.data.cart_items_list);
}
})
I`ve added a object prodqty. Then I set the prodqty whit his key. I this structure of code there may be a problem. The api use a callback, then when loop finish is posible that the prodqty object doesn´t set the values. For resolve it, You need pass a callback at the second api or wait a time until second api finish:
setTimeout(function(){ console.log(JSON.stringify(prodqty)); }, 3000);` //3 seconds for example

Unable to access JSON element

I am using the following code in Win API Controller to return an object containing a Menu object and a list of CourseOption objects.
public object GetCourseOption(int id) //Here id is Menu id
{
IEnumerable<CourseOption> courseoptions = db.CourseOptions.Where(c => c.MenuId == id);
Menu menu = db.Menus.Single(c => c.Id == id);
if (courseoptions == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
var combine = new { Menu = menu, Options = courseoptions };
return combine;
}
I can access Menu properties by using the following code in JavaScript
$.getJSON("/api/CourseOptionAPI/" + id, function (data) {
alert("In " + data.Menu.Name);
});
but unable to access CourseOption properties by the following code
alert("In " + data.Options[0].Name);
The controller method is returning Options as part of 'combine' object (i have checked it by using breakpoint).
'Menu' and 'CourseOption' are objects and 'Name' is one of their properties (in both of them) of type string.
Name may be one of the properties, but it looks like if c.MenuId == id keeps failing, you're never going to respond with any useful data and data.Options[0] will be undefined.
Like #zerkms said, console.log your incoming data and check what is in the JSON received.

Categories