Ember Handlebars helper options.inverse undefined is not a function - javascript

So I have a template and I need to show/hide some text based on a return value from a method. I searched and noticed one should use handlebars helpers in order to achieve this. So I added a resetPassword helper inside the controller. The options.fn(this) part works. The options.inverse(this) doesn't. It throws the ubiquitous JS error Uncaught TypeError: undefined is not a function....
templates/reset-password.hbs:
<div class = "container">
{{#resetPassword}}
<h4>Password has been reset</h4>
<h5>Your new password is: <b>{{password}}</b></h5>
{{else}}
<h4>Something went wrong! </h4>
<h5>The password has not been reset! Please try again later.</h5>
{{/resetPassword}}
</div>
controllers/reset-password.js:
export default Ember.Controller.extend({
token: null,
init: function ()
{
this._super();
Ember.Handlebars.registerHelper('resetPassword', function (options)
{
var token = this.get('token');
var result = false;
/* Ember.$.ajax({
type: "POST",
url: "/reset_password",
contentType: "text/html",
dataType: "json",
async: false,
beforeSend: function (request)
{
request.setRequestHeader("Authorization", token);
},
success: function (data, textStatus)
{
this.set('password', data.password);
result = true;
},
error: function (data, textStatus)
{
result = false;
}
});*/
if (result)
{
return options.fn(this);
}
return options.inverse(this);
});
}
});

So because JS and Ember purely suck, here's a workaround:
{{#if resetPassword}}
<h4>Password has been reset</h4>
<h5>Your new password is: <b>{{password}}</b></h5>
{{else}}
<h4>Something went wrong! </h4>
<h5>The password has not been reset! Please try again later.</h5>
{{/if}}
And the controller action:
resetPassword: function ()
{
var self = this;
var token = this.get('token');
var result = false;
Ember.$.ajax({
type: "POST",
url: "/api/users/reset_password",
contentType: "text/html",
dataType: "json",
async: false,
beforeSend: function (request)
{
request.setRequestHeader("Authorization", token);
},
success: function (data, textStatus)
{
var responseUser = data["users"][0];
self.set('password', responseUser.password);
result = true;
},
error: function (data, textStatus)
{
result = false;
}
});
return result;
}.property()

Related

How to set serialization in Asp .Net Core

Im getting the following error on my Ajax post back {"readyState":0,"status":0,"statusText":"error"}
on my first ajax call but the second one returns data I want.
My C# method (UserSelect) JsonResults shows the data when I put break point
My C# code :
public IActionResult OnPostAreaSelect(string Id)
{
//Generating list for Areas
Guid ModelId = new Guid(Id);
List<ModelArea> modelAreas = _context.ModelArea.Distinct()
.Where(w => w.ModelId == ModelId).OrderBy(o => o.AreaColumn.Name).Include(i => i.AreaColumn).ToList();
return new JsonResult(modelAreas);
}
public IActionResult OnPostUserSelect(string Id)
{
//Generating list for Users
Guid ModelId = new Guid(Id);
List<UserModel> userModels = _context.UserModel
.Where(w => w.ModelId == ModelId).OrderBy(o => o.User.FullName)
.Include(i => i.User)
.ToList();
return new JsonResult(userModels);
}
My JavaScript :
<script type="text/javascript">
$(document).ready(function () {
$("#RepfocusModelDropdown").change(function () {
var Id = $(this).val();
if (Id != null) {
$.ajax({
async: true,
type: "POST",
url: "./Create?handler=UserSelect",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: {
Id: Id
},
crossDomain: true,
dataType: "json",
success: function (response) {
alert(JSON.stringify(response));
},
error: function (response) {
alert(JSON.stringify(response));
}
});
$.ajax({
type: "POST",
url: "./Create?handler=AreaSelect",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: {
Id: Id
},
dataType: "json",
success: function (response) {
alert(JSON.stringify(response));
},
error: function (response) {
alert(JSON.stringify(response));
}
});
}
})
})
The second ajax call on my script works fine only the first one returns the error
How can I solve the error
When you work with EntityFramework (or other ORM) there may be problems with serialization because an entity could have some circular references. To avoid this problem a solution is to set serialization settings:
services.AddMvc().AddJsonOptions(opt => {
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
or:
Newtonsoft.Json.JsonConvert.DefaultSettings = () => new Newtonsoft.Json.JsonSerializerSettings {
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
};

How do I send files via jQuery AJAX with multiple parameter to an MVC controller?

enter code hereI have read several answers about this question, but no one works.
I have the following code but my HttpPostedFileBase[] array is always null.
The Other parameters has the right value, but the HttpPostedFileBase[] is always null.
What am i missing??
$('#myFile').on('change', function (e) {
var fileName = e.target.files[0].name;
archivosProcesar = new FormData();
for (var i = 0; i <= e.target.files.length -1; i++) {
archivosProcesar.append(i, e.target.files[i]);
}
});
function aplicarFragmentacion() {
var ids = obtenerAfiliadosSeleccionados();
var data = {
fragmento1: parseInt($('#fragmento1').val()),
fragmento2: parseInt($('#fragmento2').val()),
segmentos: ids,
archivos: archivosProcesar
}
if (!validarProcentajes() & !validarSeleccionados(ids)) {
$.ajax({
data: data,
url: urlAplicarFrag,
type: 'POST',
processData: false,
beforeSend: function () {
//$("#resultado").html("Procesando, espere por favor...");
},
success: function (data) {
onSuccessAplicarFragmentacion(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
onError(jqXHR.responseText);
}
});
}
}
Controller.cs
public async Task<ActionResult> AplicarFragmentacion(decimal fragmento1, decimal fragmento2, string[] segment\
os, HttpPostedFileBase[] archivos)
{
List<Credito> lstSegmentos = new List<Credito>();
try
{
ProgressHub.SendMessage("Iniciando proceso de fragmentación...", 10);
lstSegmentos = await FragmentacionNegocio.AplicarFragmentacion(fragmento1, fragmento2, segmentos)\
;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return Json(lstSegmentos, JsonRequestBehavior.AllowGet);
}
Try submitting a FormData object, not an anonymous object with a FormData field. Also it is my understanding that the contentType should be set to false.
var formData = new FormData();
formData.append('fragmento1', parseInt($('#fragmento1').val());
formData.append('fragmento2', parseInt($('#fragmento2').val());
formData.append('segmentos', obtenerAfiliadosSeleccionados());
formData.append('archivos', $('#fileupload')[0].files[0]);
$.ajax({
type: 'POST',
data: formData,
url: urlAplicarFrag,
type: 'POST',
processData: false,
contentType: false,
[...]
});
The fix was to use this plug in
https://jquery-form.github.io/form/
In this way
$(this).ajaxSubmit({
url: urlAplicarFrag,
data: {
fragmento1: parseInt($('#fragmento1').val()),
fragmento2: parseInt($('#fragmento2').val()),
segmentos: ids,
fechaReenvio: $('#fecha-reenvio').val()
},
success: function (data) {
onSuccessAplicarFragmentacion(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
onError(jqXHR.responseText);
}
});
check the plugin website

reactjs update state after ajax call

I want to update my state when I get errors from my ajax call.
My code:
var EmailForm = React.createClass({
getInitialState: function(){
return {
password:'',
email: '',
errors: ''
};
},
componentDidMount: function() {
this.serverRequest = $.get('/accounts/email-form/', function (result) {
var userInfo = result;
this.setState({
email: userInfo.email
});
}.bind(this));
},
submit: function (e){
var self;
e.preventDefault()
self = this;
console.log(this.state);
var data = {
password: this.state.password,
email: this.state.email,
CSRF: csrftoken
};
// Submit form via jQuery/AJAX
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.ajax({
type: 'POST',
url: '/accounts/email-form/',
data: data,
datatype: JSON
})
.done(function(data) {
toastr.success('Profile updated');
})
.error(function(jqXhr) {
var error = jqXhr.responseJSON; //How can I append this errors to my errors state ?
toastr.error('There is some errors in your request');
});
},
passwordChange: function(e){
this.setState({password: e.target.value});
},
emailChange: function(e){
this.setState({email: e.target.value});
},
render: function() {
return (
<form onSubmit={this.submit}>
<div className="form-half">
<label htmlFor="password" className="input-label">Current Password</label>
<BasicInputPassword valChange={this.passwordChange} val={this.state.password}/>
<span className="form-error is-visible">{this.state.errors.password}</span>
</div>
<div className="form-half">
<label htmlFor="email" className="input-label">New email</label>
<BasicInput valChange={this.emailChange} val={this.state.email}/>
<span className="form-error is-visible">{this.state.errors.email}</span>
</div>
<button type="submit" className="button secondary" >Submit</button>
</form>
);
}
});
I have response errors in error variable. How can I update state errors with this json and display for example state.errors.email easy ? Is this possible ?
use this.setState()
var that = this;
$.ajax({
type: 'POST',
url: '/accounts/email-form/',
data: data,
datatype: JSON
})
.done(function(data) {
toastr.success('Profile updated');
})
.fail(function(xhr, status, error) {
that.setState({
//assign error to whatever you want under `state`
});
});
*make sure this is pointing at the right scope. Or use arrow functions for lexical this.
$.get('some.php')
.done(function(msg){ })
.fail(function(xhr, status, error) {
this.setState({});///here <===
}).bind(this);
or
$.ajax({
type: "GET",
url: "test.com",
success: function(msg){
alert( "Data Saved: " + msg );
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("some error");
}
});
you must use .fail() and you can access to error in .fail() and store in state.
You can do this.
const self = this;
$.get('api-url')
.done(function(msg){
// some work
})
.fail(function(xhr, status, error) {
self.setState({error: xhr.responseJSON });
});
As the this context changes so you can assign it at a variable first to avoid the confusion with the context.

Dotnetnuke Call ajax from a module

I am now trying to build a dnn module using ajax calls. But there is a jquery error stating
SyntaxError: Unexpected token <
I have tried to work around with ajax "url: " and tried to create a new ascx at the root folder but still showing error 404.
My ajax call is as below
$.ajax({
url: "NewsManagement.ascx/Add",
contentType: "application/json; charset=utf-8",
dataType: "json",
method: "POST",
beforeSend: function () {
},
cache: false,
data: {
title : $('#txt_Title').val(),
news_content : $('#txt_Content').val(),
image : $('#file_Image').val(),
chapter_id : $('#sel_Chapter').val(),
is_draft : $('#chk_Draft').val(),
posted_date : $('#dp_PostDate').val(),
created_by : "",
lastupdate_by : ""
},
success: function (data) {
console.log(data);
if (data == "success") {
console.log(data);
}
else {
initMdlError("SERVER : " + data);
}
},
error: function (data, textStatus, error) {
// ERROR IS BEING CALLED FROM HERE
console.log("JQUERY JAVASCRIPT : " + error);
initMdlError(error);
},
complete: function () {
console.log('complete');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Is there any way to solve the issues?
The problem you're running into is that DNN isn't handling the requested URL properly that you are calling. If you want to call a service URL in DNN you're going to want to setup routes to handle the calls.
namespace Christoc.Com.Modules.SlidePresentation.services
{
public class SlidePresentationRouteMapper : IServiceRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapRoute("SlidePresentation", "{controller}.ashx/{action}",
new[] {"Christoc.Com.Modules.SlidePresentation.services"});
}
}
}
In the Controller you can define the methods available
[DnnAuthorize(AllowAnonymous = true)]
public ActionResult ListOfSlides()
{
try
{
var slides = Slide.GetSlides(ActiveModule.TabID, ActiveModule.ModuleID);
return Json(slides, JsonRequestBehavior.AllowGet);
}
catch (Exception exc)
{
DnnLog.Error(exc);
return Json(null, JsonRequestBehavior.AllowGet);
}
}
https://slidepresentation.codeplex.com/SourceControl/latest#DesktopModules/SlidePresentation/services/SlidePresentationController.cs
sample Javascript
//get slides on initialization
this.init = function(element) {
//var data = {}; //removed because we don't need this
//data.moduleId = moduleId; //removed because we don't need this when calling setModuleHeaders
//data.tabId = tabId; //removed because we don't need this
//serviceFramework.getAntiForgeryProperty(); //removed because we don't need this
$.ajax({
type: "POST",
cache: false,
url: baseServicePath + 'ListOfSlides',
//data: data,
//dataType:"json",
beforeSend: serviceFramework.setModuleHeaders
}).done(function(data) {
viewModel.slides = ko.utils.arrayMap(data, function(s) {
return new slide(s);
});
ko.applyBindings(viewModel);
$(element).jmpress();
}).fail(function () {
Console.Log('Sorry failed to load Slides');
});
};
Here's an example module that does this
https://slidepresentation.codeplex.com/
And a user group video I did years ago on this module.
https://www.youtube.com/watch?v=hBqn5TsLUxA

handle jquery ajax error

in my MVC layout page I have the following:
$("body").ajaxError(
function (e, request) {
if (request.status == 403 || request.status == 500) {
window.location = '#Url.Action("LogOn", "Account", new {area = "", msg = "forbidden", returnUrl = HttpContext.Current.Request.RawUrl})' + window.location.hash;
return;
}
window.location = '#Url.Action("Index", "Error")';
}
);
on another page I'm performing an ajax call like so:
...
$.when(refreshActionLinks(row, machineId, packageId)).done(function(a1) {
row.find("span").text(opStatus).removeClass("pending");
progressbar.progressbar("destroy");
$(row).flash(bg[1], 1000);
});
...
javascript function:
function refreshActionLinks($row, machineId, packageId) {
try {
var json = JSON.stringify({ packageId: packageId, machineId: machineId, tabType: $("#TabType").val() });
console.log("refreshActionLinks => " + json);
$row.find("td.options div.actionLinks").html("<img src='#Url.Content("~/Content/images/ajax-load2.gif")' />"); // pending
return $.ajax({
url: "#Url.Action("GetActionLinks", "Packages")",
data: json,
timeout: 50000,
contentType: 'application/json',
type: 'POST',
success: function (data) {
if ($row.length) {
$row.find("td.options div.actionLinks").html(data);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
} catch(e) {
// hide icons
$row.find("a.action").remove();
}
}
The issue is that while refreshAction function is executing, clicking a menu link causes the ajax call to error out - which in this case is correct. BUT it does take me to /Index/Error page which is NOT correct. I would like "$("body").ajaxError" to handle all ajax errors on the site EXCEPT on the page I'm calling refreshActionLinks. Notice, I already have try/catch surrounding my ajax call. why doesn't that work?
thanks
figured it out:
ajax has a settings:
global: false
now my function looks like this:
function refreshActionLinks($row, machineId, packageId) {
try {
var json = JSON.stringify({ packageId: packageId, machineId: machineId, tabType: $("#TabType").val() });
console.log("refreshActionLinks => " + json);
$row.find("td.options div.actionLinks").html("<img src='#Url.Content("~/Content/images/ajax-load2.gif")' />"); // pending
return $.ajax({
url: "#Url.Action("GetActionLinks", "Packages")",
global: false, // disable error pages on failed ajax calls
data: json,
timeout: 50000,
contentType: 'application/json',
type: 'POST',
success: function (data) {
if ($row.length) {
$row.find("td.options div.actionLinks").html(data);
}
}
});
} catch(e) {
// hide icons
$row.find("a.action").remove();
}
}

Categories