Javascript `this` statement not working - javascript

After calling this $http request (with server.refresh();)
MinecraftServer.prototype.refresh = function(){
return $http.get("http://mcping.net/api/" + this.ip).then(this.acceptData);
}
This function's this is the window object, instead of the MinecraftServer object:
MinecraftServer.prototype.acceptData = function(data){
data = data.data
if(data && data.online){
this.online = data.online;
//do more stuff
} else { // do more stuff }
}
So instead of the MinecraftServer object getting it's attributes updated, the window gets the attributes.
In case this will help, here is my abriged factory code:
.factory('MinecraftServer',function($http){
function MinecraftServer(name, ip) { //does stuff }
MinecraftServer.prototype.acceptData = function(data){
data = data.data
if(data && data.online){
this.online = data.online;
//do more stuff
} else { // do more stuff }
}
MinecraftServer.prototype.refresh = function(){return $http.get("http://mcping.net/api/" + this.ip).then(this.acceptData);}
MinecraftServer.build = function(name, ip){return new MinecraftServer(name, ip)};
return MinecraftServer;
})

this as a callback is using some other this.
Use .bind:
return $http.get("http://mcping.net/api/" + this.ip).then(this.acceptData.bind(this));

Related

Save changes function not properly updating the database

So, I have a button that triggers a javascript function, that calls an AJAX request, that calls an actionresult that should update my database.
Javascript Call
function changeDepartment() {
// Initiate and value variables,
var id = $('#requestId').val();
var user = $('#contactUser').val();
// Bind variables to data object
var data = { id: id }
// Ajax call with data.
$.ajax({
url: '#Url.Action("changeDepartmentActionResult", "ManageRequestResearch")',
type: "POST",
dataType: 'json',
data: data,
success: function (data, textStatus, XmlHttpRequest) {
var name = data.name;
window.location.href = '#Url.Action("Index", "ManageRequestResearch")';
$('#btn-input').val('');
},
error: function (jqXHR, textStatus, errorThrown) {
alert("responseText: " + jqXHR.responseText);
}
});
alert(data);
And then, I have the action result:
[HttpPost]
public ActionResult changeDepartmentActionResult(string id)
{
var moadEntities = new MOADEntities();
moadEntities.Configuration.AutoDetectChangesEnabled = false;
var researchBusiness = new ResearchRequestBusiness(moadEntities);
var request = researchBusiness.FetchRequestById(Convert.ToInt32(id));
var directoryObject = GetActiveDirectoryObject(request.Requestor);
var requstorDisplayName = directoryObject != null ? directoryObject.DisplayName : request.RequestorFullName;
var researchRequestFileBusiness = new ResearchRequestFilesBusiness(moadEntities);
var requestFiles = researchRequestFileBusiness.FetchFilesByRequestId(Convert.ToInt32(id));
var viewModel = new ManageSelectedRequestResearchViewModel()
{
RequestDetails = request,
RequestActivity = request.tbl_ResearchRequestActivity.Select(d => d).ToList(),
Files = requestFiles
};
moadEntities.Configuration.AutoDetectChangesEnabled = false;
if (request.GovernmentEnrollment == true)
{
request.GovernmentEnrollment = false;
request.ManagedCare = true;
moadEntities.SaveChanges();
}
else
{
request.ManagedCare = false;
request.GovernmentEnrollment = true;
moadEntities.SaveChanges();
}
return Json("Status changed successfully", JsonRequestBehavior.AllowGet);
}
From what I have observed, it returns the right record, it makes the changes properly, and it hits the Context.SaveChanges();
when debugging -- i can see before the save changes is made that the values have indeed changed, however--inside the database, no changes are saved.
In addition, i have checked to see that the connection strings are valid.
Any idea what may be causing this?
Thanks ahead of time!
It seems that you are modifying an entity while auto detecting changes are disabled.
If it is intentional then you should inform the context that the entity has been changed.
I assume that MOADEntities is derived from DbContext. So instead of this:
if (request.GovernmentEnrollment == true)
{
request.GovernmentEnrollment = false;
request.ManagedCare = true;
moadEntities.SaveChanges();
}
else
{
request.ManagedCare = false;
request.GovernmentEnrollment = true;
moadEntities.SaveChanges();
}
I would try this:
// Simplify the if..else block
request.ManagedCare = request.GovernmentEnrollment;
request.GovernmentEnrollment = !request.GovernmentEnrollment;
// Notifying the context that the 'request' entity has been modified.
// EntityState enum is under System.Data.Entity namespace
moadEntities.Entry(request).State = EntityState.Modified;
// Now we can save the changes.
moadEntities.SaveChanges();

Submit Form as JSON with Play Framework

I am trying to submit a form as a JSON object because I want to create a REST API with play.
The issue that I have is that Play tells me that is not a valid JSON.
My FORM code:
#(form : Form[Product]) #main("Create Form"){
#helper.form(routes.Products.createProduct, 'enctype -> "application/json"){
#helper.inputText(form("name"))
<button>Commit</button>
} }
Controller Code:
// Read JSON an tell if it has a name Path
#BodyParser.Of(BodyParser.TolerantJson.class)
public static Result createProduct() {
JsonNode json = request().body().asJson();
String name = json.findPath("name").textValue();
if (name == null) {
return badRequest("Not JSON");
} else {
return ok(name);
}
}
Whats the best way to do this? a read about submitting with Ajax but because I am new with play I don´t figure it out the way to do this with Play´s form syntax.
You can do it easily with jQuery (so make sure you have jQuery included in your head) and formAsJson() function based on serializeObject function.
#helper.form(routes.Products.createProduct(), 'id -> "myform") {
#helper.inputText(jsonForm("name"))
<button>Commit</button>
}
<script>
$.fn.formAsJson = function(){
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return JSON.stringify(o)
};
var $myform = $("#myform");
$myform.on('submit', function () {
$.ajax({
url: $myform.attr('action'),
type: $myform.attr('method'),
contentType: "application/json",
data: $myform.formAsJson(),
success:function(){
alert("Great! Everything's OK!");
},
error: function(){
alert("Booo, something wrong :(");
}
});
return false;
});
</script>
and your createProduct() action could look just like:
public static Result createProduct() {
JsonNode json = request().body().asJson();
String name = json.findPath("name").textValue();
if (json==null || name==null || ("").equals(name.trim())){
return badRequest();
}
return ok();
}

Test if localStorage is full

I am learning about localStorage and it sounds like each browser gives a domain 5MB.
I wrote this code to cache the data returned from an ajax call and it works. But how do I test to see if localStorage is full? If there is no localStorage space available I imagine that the ajax request should be made again.
Here's my code:
if ( localStorage && localStorage.getItem('myGithub') ) {
console.log('if statement');
console.log( JSON.parse( localStorage.getItem( 'myGithub') ) );
render( JSON.parse( localStorage.getItem( 'myGithub') ) );
}
else {
console.log('else statment');
$.ajax({
url : 'https://api.github.com/users/xxxxxxxxx',
dataType : 'json',
success : function (data) {
if ( localStorage ) {
localStorage.setItem( 'myGithub', JSON.stringify(data) );
}
console.log(data);
render(data);
}
});
}
//Render method for printing the results to the <body> element.
//Returns html from the ajax call or from localStorage.
function render (myObjx) {
var results = '';
for (var prop in myObjx) {
results += '<p>data.' + prop + ' = ' + myObjx[prop] + '</p>';
}
var printData = $('body').html(results);
return printData;
};
You can use the below approach. You can change it as per your requirement.
function checkAvailable(){
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
// And you call below to check the availablity
if(checkAvailable() === true){
// available
}else{
// unavailable
}

What design pattern should I apply when checking multiple ajax request completion?

I have 3 ajax call in one function and checkAjaxCompletion which checks each ajax completion flag.
What the code below does is send multiple separate ajax calls and interval method checks completion flags to determine whether to proceed or keep interval. (I know clearInterval is not shown but the point is I want to use something other than interval)
Current code is:
function manyAjax() {
setInterval( function() { checkAjaxCompletion(); } , 200);
ajax1();
ajax2();
ajax3();
}
function ajax1() {
//send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}
function ajax2() {
//send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}
function ajax3() {
//send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}
function checkAjaxCompletion() {
if(ajax1_flag == 1 && ajax2_flag == 1 && ajax3_flag == 1) {
//everything went success, do some process
}
else if(ajax1_flag == 2 || ajax2_flag == 2 || ajax3_flag == 2) {
//some ajax failed, do some process
}
else {
//all ajax have not been completed so keep interval i.e. do nothing here
}
}
But I'm hesitating to depend on using interval function because calling it so often seem such waste of memory. There must be better way to do. I'm thinking if observer pattern can be applied here but would like to hear opinions.
It is observer-notifier, if you want to call it that - but each of your ajax calls will more than likely have a callback in javascript when they complete. Why not call checkAjaxCompletion() at the end of each of them, and do nothing if you're still waiting on others?
Dustin Diaz does a great job with this example.
function Observer() {
this.fns = [];
}
Observer.prototype = {
subscribe : function(fn) {
this.fns.push(fn);
},
unsubscribe : function(fn) {
this.fns = this.fns.filter(
function(el) {
if ( el !== fn ) {
return el;
}
}
);
},
fire : function(o, thisObj) {
var scope = thisObj || window;
this.fns.forEach(
function(el) {
el.call(scope, o);
}
);
}
};
The publisher:
var o = new Observer;
o.fire('here is my data');
The subscriber:
var fn = function() {
// my callback stuff
};
o.subscribe(fn);
To unsubscribe:
var fn = function() {
// my callback stuff
};
o.subscribe(fn);
// ajax callback
this.ajaxCallback = function(){
$.ajax({
type: "POST",
url: ajax.url,
data: {key: value},
async : !isAll,// false使用同步方式执行AJAX,true使用异步方式执行ajax
dataType: "json",
success: function(data){
if(data.status == 'successful'){
selfVal.parent().find('.msg').addClass('ok').html(msg.ok);
}else if(data.status == 'failed'){
checkRet = false;
selfVal.parent().find('.msg').removeClass('ok').html(msg.error);
}else{
checkRet = false;
}
return this;
}
});
}
return this;
Maybe you want to check your inputvalue callback ajax in your form;
You can view my website Demo, hope help you.
http://6yang.net/myjavascriptlib/regForm
Okay my idea was to make your own object that can handle sending an array of requests, keep a history of each request and do what i'm gonna call 'postProccessing' on each response, here is a probably very dodgy bit of code to hopefully demonstrate what I am thinking.
var Ajax = function() {
var request, callback, lst;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
request.onreadystatechange = handleResponse;
this.history = [{}];
this.send = function(args) {
for (var i = 0; i < args.length; i++) {
if (args.url) {
request.open(args.type || 'GET', args.url);
}
request.send(args.data || null);
callback = args.callback;
lst++;
}
}
function handleResponse() {
var response = {
url: '',
success: true,
data: 'blah'
};
history.push(response);
if (postProccess()) {
callback();
}
}
function postProcess() {
if (this.history[lst].success) {
return true;
} else {
return false;
}
}
}

I am not getting the alert javascript on my controller page

I have this code in my ActionResult
public ActionResult Copy( int bvVariableid ) {
var iReturn = _bvRepository.CopyBenefitVariable( bvVariableid, CurrentHealthPlanId, CurrentControlPlanId, _bvRepository.GetSecInfo( ).UserId, IsNascoUser());
if (iReturn == -999)
return new JavaScriptResult() { Script = "alert(Unique variable name could not be created');" };
if( iReturn != -1 )
return Json( new { RedirectUrl = string.Format( "/BvIndex/Index/{0}?bvIndex-mode=select", iReturn ) } );
return RedirectToRoute( "Error" );
}
This is the code i have in my View.
CopyBenefitVariable = function (bvId, bvName) {
if (confirm('Are you sure you want to copy from the Benefit Variable ' + bvName + ' ?')) {
$.post(
"/BvIndex/Copy/",
{ bvVariableid: bvId },
function (data) {
window.location = data.RedirectUrl;
}, "json");
}
};
When IReturn is -999 I am not getting the JavaScriptResult alert box on my page.
is that something I am doing wrong here?
Can any body help me out.
Thanks
I thing, there is a bug in this line:
return new JavaScriptResult() { Script = "alert(Unique variable name could not be created');" };
Corrected :
return new JavaScriptResult() { Script = "alert('Unique variable name could not be created');" };
Your problem is likely stemming from your client-side JavaScript. The .post() method in ajax is actually a shortcut for:
$.ajax({
type: 'POST',
url: url,
data: data,
success: success,
dataType: dataType
});
So your client-side code is telling jQuery to interpret the result as a json object (even though you sent back a script).
$.post(
"/BvIndex/Copy/", // url
{ bvVariableid: bvId }, // data
function (data) {
window.location = data.RedirectUrl; // success
},
"json" // dataType
);
I would change your code to look like this:
public ActionResult Copy( int bvVariableid ) {
var iReturn = _bvRepository.CopyBenefitVariable( bvVariableid, CurrentHealthPlanId, CurrentControlPlanId, _bvRepository.GetSecInfo( ).UserId, IsNascoUser());
if (iReturn == -999)
return new Json(new { type = "msg", data = "Unique variable name could not be created" });
if( iReturn != -1 )
return Json( new { type = "url", data = string.Format( "/BvIndex/Index/{0}?bvIndex-mode=select", iReturn ) } );
return RedirectToRoute( "Error" );
}
And your view code should look like this:
CopyBenefitVariable = function (bvId, bvName) {
if (confirm('Are you sure you want to copy from the Benefit Variable ' + bvName + ' ?')) {
$.post(
"/BvIndex/Copy/",
{ bvVariableid: bvId },
function (data) {
if (data.type == "url") {
window.location = data.RedirectUrl;
} else if (data.type == "msg") {
alert(data.data);
}
}, "json");
}
};
You can mark down my answer if you like, but it is generally accepted that the JavaScriptResult was a bad move on the ASP.NET MVC team's part. That being said, your sample already returns a Json Action Result for one of your conditions. You could do the same for both items. If you altered your JSON object like:
return Json( new { success = bool, RedirectUrl = value } );
Then you could change your client function to something like:
function (data) {
if(data.success === true) {
window.location = data.RedirectUrl;
} else {
alert('Unique variable name could not be created');
}
}
I know it doesn't directly address the issue with JavaScriptResult, but it should get the intended result of the code.

Categories