Event Handlers in a JavaScript "class" - javascript

I am working at fully understanding class definitions in JavaScript. Currently, I have a class defined like the following:
function Item() { this.init(); }
Item.prototype = {
init: function () {
this.data = {
id: 0,
name: "",
description: ""
}
},
save: function() {
$.ajax({
url: getUrl(),
type: "POST",
data: JSON.stringify(this.data),
contentType: "application/json",
success: save_Succeeded,
error: save_Failed
});
}
}
My problem is, I'm not sure how, or where, to define my save_Succeeded and save_Failed event handlers. Can someone please help me out? Thank you!

Add a context: to your $.ajax call pointing to this so that the correct object is passed as this when the handlers are called.
Something like:
save: function() {
$.ajax({
context: this,
url: getUrl(),
type: "POST",
data: JSON.stringify(this.data),
contentType: "application/json",
success: this.save_Succeeded,
error: this.save_Failed
});
(assuming that you also put save_Succeeded and save_Failed into the prototype)
}

Related

In a JS class an AJAX success callback keeps returning Uncaught TypeError but the method is defined and I have no idea what's up [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 2 years ago.
I am making a successful AJAX call which returns data but I keep getting sortable.class.js:50 Uncaught ReferenceError: buildTabs is not defined in the success handling and I cannot figure out what the problem is.
Does anyone see what's wrong with this?
Instantiated and called with
const sortable = new Sortable();
sortable.v2Test();
The Class(shortened)
class Sortable {
constructor() {}
v2Test() {
this.v2Tabs();
}
buildTabs(dataset) {
console.log('working');
}
v2Tabs() {
$.ajax({
type: 'GET',
url: '/v2/tabs',
contentType: 'application/json',
success: function (data) {
buildTabs(data);
},
});
}
}
===== Working version with passed function ====
this.v2Icons(1, 'tab1', this.processIcons); //call
v2Icons(tab, targetElement, callback) {
$.ajax({
type: 'GET',
url: '/v2/icons/' + tab,
contentType: 'application/json',
success: function (data) {
callback(targetElement, data.icons, data.maxrow);
},
});
}
processIcons(targetElement, dataset, maxrow) {
// do the shizzle
});
success function doesn't have reference to the parent object methods without a reference, to fix this you can use arrow function which bind to the parent by default:
class Sortable {
constructor() {}
v2Test() {
this.v2Tabs();
}
buildTabs(dataset) {
console.log('working');
}
v2Tabs() {
$.ajax({
type: 'GET',
url: '/v2/tabs',
contentType: 'application/json',
success: (data) => {
this.buildTabs(data);
},
});
}
}

Why does inner method's inside execute last?

At following method i'm trying to get grid selected row. By the way, i use syncfusion component library.
My question when i call the grid.rowSelected, function's inside works last. So i can't pass model in ajax.
What's the reason of it ?
function editPackage() {
var editPackageModel;
var grid = document.getElementById("Grid").ej2_instances[0];
grid.rowSelected = function(args) {
console.log(args.data);*// works last*
editPackageModel = args.data;*// works last*
}
$.ajax({
type: "GET",
url: "/Package/Edit",
contentType: "application/json; charset=utf-8",
datatype: "json",
data: editPackageModel,
success: function (result) {
$('#generalModal').html(result);
},
error: function () {
alert("Dynamic content load failed.");
}
});
}
I'm not sure exactly what is the situation with "grid", i assume you have that element ready before the function is called, so try this:
var grid = document.getElementById("Grid").ej2_instances[0];//Get node reference.
grid.rowSelected = function (args) {//Setup event listener.
editPackage(args.data);//Pass the data from the event to your function
}
function editPackage(editPackageModel) {//Get the "model" and send ajax
$.ajax({
type: "GET",
url: "/Package/Edit",
contentType: "application/json; charset=utf-8",
datatype: "json",
data: editPackageModel,
success: function (result) {
$('#generalModal').html(result);
},
error: function () {
alert("Dynamic content load failed.");
}
});
}

Calling a controller method via javascript

I have an ASP.NET application where I am invoking a controller methode from JavaScript. My JavaScript code looks like this:
function OnNodeClick(s, e) {
$.ajax({
type: "POST",
url: '#Url.Action("DeviceManifests", "Home")',
data: { selectedRepo: e.node.name },
success: function (data) {
if (data != null) {
$('#GridView').html(data);
}
},
error: function (e) {
alert(e.responseText);
}
});
}
This calls the Home controller's DeviceManifests() method.
This is what the method looks like:
public ActionResult DeviceManifests(Guid selectedRepo)
{
var repoItem = mock.GetRepoItem(selectedRepo);
return View("Delete", repoItem.childs);
}
The method gets invoked but the problem is the Delete-View doesn't get rendered. There's no error, just nothing happens.
How can I update my code to get my desired behaviour?
Do like below code so if you have error you will have it in alert box or success result will rendered in DOM
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: '#Url.Action("DeviceManifests", "Home")',
data: { selectedRepo: e.node.name },
dataType: "html",
success: function (data) {
if (data != null) {
$('#someElement').html(data);
}
}
},
error: function (e) {
alert(e.responseText);
}
});
You can do the redirect in the javascript side.
function OnNodeClick(s, e) {
$.ajax({
type: "GET ",
url: '#Url.Action("DeviceManifests", "Home")',
data: { selectedRepo: e.node.name },
success: function (msg)
{
window.location = msg.newLoc;
}
});
}
Make sure you include the redirect url in action and return JsonResult and not ActionResult. I'd also include pass the guid so that the destination Action and let it look up the data.

Finding a circular object in the code

I am writing a script using jQuery for loading some content into my page.
At runtime nothing happens. I get this error when inspecting Firebug console:
TypeError: cyclic object value
data: JSON.stringify({ columnName: _columnName })
Here is the code (placed inside <Head>):
<Script>
function changeContent(_columnName) {
$.ajax({
type: 'POST',
url: '#Url.Action("GetContent")',
data: JSON.stringify({ columnName: _columnName }),
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).done(function (resp) {
CKEDITOR.instances.text.setData(resp.Text);
}).fail(function () {
alert("Error");
});
}
$(function () {
$("#side-content").bind('click', { a: "side" }, changeContent);
});
</Script>
I used the tip here: Detecting and fixing circular references in JavaScript but could not find any circular relations!!!
Any point on saving my life would be so greatly appreciated.
- Kamran
Problem solved and well understood
The main part of the problem was I did not know that the argument of the handler is DOM event. I thought that _columnName will receive event data which was wrong. It is DOM event in fact.
The working code follows:
<script>
function changeContent(event) {
$.ajax({
type: 'POST',
url: '#Url.Action("GetHomeColumnContent")',
data: JSON.stringify({ columnName: event.data.a }),
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).done(function (resp) {
CKEDITOR.instances.text.setData(resp.Text);
}).fail(function () {
alert("Error");
});
}
$(function () {
$("#side-content").bind('click', { a: 'side' }, changeContent);
});
</script>
And about the cyclic value: DOM elements are cyclic in nature because every DOM element has a reference to its parent, and in turn every parent has references to its children, so a cyclic structure.
Thanks to all friends for their times: #Dogbert, #nnnnnn, #AD7six, #Xotic750 ;-)

calling method in javascript, but error throws?

I need to call ajax method couple of places. So want to try to minimize the code by creating separate method for it. If use directly, it works perfect. but when I separate it won't work.
data: columns[5],
type: 'autocomplete',
options: { items: 100 },
source: function (query, process) {
$.ajax({
url: "/EditInitiatives.svc/GetLocationData?clientId=" + $value.val(),
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {
query: query
},
success: function (response) {
process(response.d);
}
});
},
strict: true
}
it doesn't work, if I call this way. It says Microsoft JScript runtime error: 'query' is undefined, how to fix it?
{
data: columns[4],
type: 'autocomplete',
options: { items: 100 },
source: callAutoCompleteAjaxMethod(query, process, "/EditInitiatives.svc/GetLocationData?clientId=" + $value.val()),
strict: true
},
callAutoCompleteAjaxMethod = function (query, process, url) {
$.ajax({
url:url,
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {
query: query
},
success: function (response) {
process(response.d);
}
});
},
You call
source: callAutoCompleteAjaxMethod(query, ...
But you never gave 'query' a value, give it a value and it will work.
You are calling the function instead of assigning it to the source property. And at this moment the variable query is not defined.
You have to assign a function, so that the plugin can call it later:
source: function (query, process) {
callAutoCompleteAjaxMethod(
query,
process,
"/EditInitiatives.svc/GetLocationData?clientId=" + $value.val()
);
}
(I hope $value is defined somewhere)
Parenthesis ( () ) after a function reference always calls the function immediately. If you want to pass a reference to the function, you don't put parenthesis after it.

Categories