$.parseJSON(data, true) throws - javascript

I am working in ASP.NET MVC 5.
I am trying to deserialize dates coming from the server in JSON format. The JSON arrives and when I try to deserialize the dates the debugger just stops and don't show any errors other the in the console, which I can't understand.
This is my code so far:
$(document).ready(function () {
$.ajax({
type: 'GET',
url: '/Home/GetDates',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (dates) {
var date = dates[0];
var desDate = $.parseJSON(date, true);
console.log(desDate);
}
});
});
Here are some pics on the errormessage and that a have data coming in.
Here is a link to the docs I have been looking at. Docs

The data returned from the ajax call is already parsed, so dates is an array containing strings, and dates[0] is the string/Date(14984....)/ etc.
To parse the string, remove everything but the numbers, and use that timestamp to create a Date object.
$(document).ready(function () {
$.ajax({
type : 'GET',
url : '/Home/GetDates',
dataType : "json",
contentType : "application/json; charset=utf-8",
success: function (dates) {
var d = dates[0];
var unix = +d.replace(/\D/g, '');
var date = new Date(unix);
var desDate = date.getFullYear() + '/' +
(date.getMonth()+1) + '/' +
date.getDate();
console.log(desDate);
}
});
});

You need to execute the JavaScript inside your string variable as
var dateVar = eval(dates[0]);
This will give you the date but not in a proper format which you want. For the proper format user either moment.js or simply create your own lines of code like
var finalDate = new Date(dateVar).toISOString().split('T')[0];
console.log(finalDate);
The new Date() is again needed here so that we can make use of toISOString() and get the proper date format.

Because you are referring to this jQuery parseJSON automatic date conversion for Asp.net and ISO date strings you need to include the jQuery extension defined there.
Indeed, in jQuery parseJSON(jsonString) accepts only one argument while you are using an extension.
Moreover, your dates variable is an array of string, and not a json string.
//
// Look at the end....
//
/*
* jQuery.parseJSON() extension (supports ISO & Asp.net date conversion)
*
* Version 1.0 (13 Jan 2011)
*
* Copyright (c) 2011 Robert Koritnik
* Licensed under the terms of the MIT license
* http://www.opensource.org/licenses/mit-license.php
*/
(function ($) {
// JSON RegExp
var rvalidchars = /^[\],:{}\s]*$/;
var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
var dateISO = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.,]\d+)?Z/i;
var dateNet = /\/Date\((\d+)(?:-\d+)?\)\//i;
// replacer RegExp
var replaceISO = /"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:[.,](\d+))?Z"/i;
var replaceNet = /"\\\/Date\((\d+)(?:-\d+)?\)\\\/"/i;
// determine JSON native support
var nativeJSON = (window.JSON && window.JSON.parse) ? true : false;
var extendedJSON = nativeJSON && window.JSON.parse('{"x":9}', function (k, v) {
return "Y";
}) === "Y";
var jsonDateConverter = function (key, value) {
if (typeof(value) === "string") {
if (dateISO.test(value)) {
return new Date(value);
}
if (dateNet.test(value)) {
return new Date(parseInt(dateNet.exec(value)[1], 10));
}
}
return value;
};
$.extend({
parseJSON: function (data, convertDates) {
/// <summary>Takes a well-formed JSON string and returns the resulting JavaScript object.</summary>
/// <param name="data" type="String">The JSON string to parse.</param>
/// <param name="convertDates" optional="true" type="Boolean">Set to true when you want ISO/Asp.net dates to be auto-converted to dates.</param>
if (typeof data !== "string" || !data) {
return null;
}
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = $.trim(data);
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if (rvalidchars.test(data
.replace(rvalidescape, "#")
.replace(rvalidtokens, "]")
.replace(rvalidbraces, ""))) {
// Try to use the native JSON parser
if (extendedJSON || (nativeJSON && convertDates !== true)) {
return window.JSON.parse(data, convertDates === true ? jsonDateConverter : undefined);
}
else {
data = convertDates === true ?
data.replace(replaceISO, "new Date(parseInt('$1',10),parseInt('$2',10)-1,parseInt('$3',10),parseInt('$4',10),parseInt('$5',10),parseInt('$6',10),(function(s){return parseInt(s,10)||0;})('$7'))")
.replace(replaceNet, "new Date($1)") :
data;
return (new Function("return " + data))();
}
} else {
$.error("Invalid JSON: " + data);
}
}
});
})(jQuery);
var date = '{"date": "\\/Date(1498435200000)\\/"}';
var desDate = $.parseJSON(date, true);
console.log(desDate);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Kendo jQuery Spreadsheet Date Values on Save

So I have a Kendo jQuery spreadsheet that is bound to a remote datasource. The fields in the spreadsheet are also data-driven, so I have a process in place that will loop over all of the columns and apply a validation to the column based on the type of data. When I apply the validation to date values it seems like all the values are converted into JavaScript Date objects.
This causes me two problems. 1. When I go to save the data it sends the date object to the server, not a string of the mm/dd/yyyy. 2. It treats blank values as 12/30/1899.
Here is a portion of the code that I use:
var record_id = 1;
var columnData = {
field_name1: {"title":"FIELD1", "type":"string", "width":50, "order":0},
field_name2: {"title":"FIELD2", "type":"date", "width":50, "order":1}
};
var columnMap = ['field_name1', 'field_name2'];
// The following code executes in the event that is triggered when the data is successfully read.
function readSource(e) {
$.ajax({
url: './spreadsheet.php',
data: { id: record_id, action: 'list' },
dataType: 'json',
method: 'POST',
success: function(result) {
e.success(result);
$.each(columnData, function(field, data) {
var range = toColumnName(columnMap.indexOf(field) + 1) + '2:' + toColumnName(columnMap.indexOf(field) + 1) + (result.count + 1);
var validator = false;
var format = '';
switch (data.type) {
case 'date': {
validator = {
dataType: 'date',
comparerType: 'between',
from: 'DATEVALUE("1/1/2000")',
to: 'DATEVALUE("1/1/2100")',
allowNulls: true,
showButton: true,
type: 'reject',
titleTemplate: 'Date Error',
messageTemplate: 'Enter a valid date between 1/1/2000 and 1/1/2100.'
};
format = 'mm/dd/yyyy';
break;
}
}
if (validator !== false) {
sheet.range(range).validation(validator);
}
if (format === '') {
sheet.range(range).format(format);
}
});
}
});
}
// On save
function submitSource(e) {
$.ajax({
url: './spreadsheet.php',
data: { action: 'update', id: record_id, records: e.data },
method: 'POST',
dataType: 'json',
success: function (result) {
e.success(result.Updated, 'update');
e.success(result.Created, 'create');
e.success(result.Destroyed, 'destroy');
}
}
// Convert index to column letter (1 => 'A', 27=>'AA')
function toColumnName(num) {
for (var ret = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) {
ret = String.fromCharCode(parseInt((num % b) / a) + 65) + ret;
}
return ret;
}
I will include a link to a screenshot that shows what happens to cells that should be blank when I click the save button. The first row in the image had dates that were populated. The rows below that were blank.
What needs to change to allow the appropriate date values to be sent back to the server and how can I avoid the trouble with the blanks?
The spreadsheet.php code probably doesn't properly format the date.
December 30, 1899 is the epoch date for Microsoft Excel and others:
https://en.wikipedia.org/wiki/Epoch_(reference_date)#Notable_epoch_dates_in_computing
So you are probably feeding the value "1" instead of null.

Convert from JSON to array of objects

I'm trying to convert an array of Hazards(class that i created) to JSON,
this is my code:
$.ajax({
async: true,
url: web + "/GetHazards",
method: "POST",
contentType: "application/json",
success: function (data) {
var res = data.d;
var i;
alert(res[0]);
the returned data is like this :
"[{\"Hazard_ID\":3014,\"Hazard_Lat\":32.2615929,\"Hazard_Long\":35.01423},{\"Hazard_ID\":3013,\"Hazard_Lat\":32.3426857,\"Hazard_Long\":34.9103165},{\"Hazard_ID\":3012,\"Hazard_Lat\":32.3426857
My server side code returns the correct values that i need, but the problem is when i alert the res[i] it behave like res is a string and alerts me "["
what i need to get is
{\"Hazard_ID":3014,\"Hazard_Lat\":32.2615929,\"Hazard_Long\":35.01423}
i dont know if it mind this is my server-side code by the way:
{
List<Returned_Hazard> rh = new List<Returned_Hazard>();
JavaScriptSerializer json = new JavaScriptSerializer();
.
.
.
while (reader.Read())
{
Returned_Hazard RH = new Returned_Hazard(
int.Parse(reader[0].ToString()),
float.Parse(reader[1].ToString()),
float.Parse(reader[2].ToString())
);
rh.Add(RH);
}
command.Connection.Close();
return json.Serialize(rh);
}
You need to parse the JSON, using JSON.parse:
var data = { d: "[{\"Hazard_ID\":3014,\"Hazard_Lat\":32.2615929,\"Hazard_Long\":35.01423},{\"Hazard_ID\":3013,\"Hazard_Lat\":32.3426857,\"Hazard_Long\":34.9103165}]"
};
var res = JSON.parse(data.d);
console.log(res[0].Hazard_ID); //3014

Sending a parameter from Javascript to a controller

I'm modifying an ASP.NET project that I didn't worked on before.
I added a datepicker object :
<input id="datepicker" />
<script>
$("#datepicker").kendoDatePicker({
value: new Date()
change: UpdateVehiculesSurSite
});
</script>
And tried to modify the "UpdateVehiculesEnAttente" method to send the date picked to my controller :
function UpdateVehiculesEnAttente(){
var datepicker = $("#datepicker").data("kendoDatePicker");
console.log(typeof datepicker);
if (datepicker!==null && typeof datepicker !== "undefined"){
var value = datepicker.value();
console.log(value);
value = kendo.toString(value,"dd/MM/yyyy")
alert(value);
$(document).ready($.ajax({
url: 'Entrees_Sorties/Get_Vehicules_EnAttente',
type: 'POST',
data: {'date' : value},
contentType: 'application/json',
success: function (retour) {
$("#DivVehiculesEnAttente").html(retour);
console.log("update attente success");
},
error: function (xhr, status, error) {
montrerNotificationNoConnexion();
}
}));
//}
return false;
}
The first problem is that the project run the javascript file first, so the datepicker isn't initialized. To try my Controller method, I gave "value" a date.
My controller method is the following :
public ActionResult Get_Vehicules_EnAttente([DataSourceRequest] DataSourceRequest request, string date){
try{
List<List<Vehicule>> Data = new List<List<Vehicule>>();
DateTime dt = Convert.ToDateTime(date);
Data.Add(Models.Vehicule.Get_Vehicules_EnAttente_ByDate(dt, true));
return PartialView("VehiculesEnAttente", Data);
} catch (Exception e) {
WorkflowWCF.Log.enregistrer_erreur(new Exception("Une erreur est survenue lors de la récupération des véhicules planifiés", e));
return Json(new List<Vehicule>().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
}
The result is that my Ajax request return error and launch the "montrerNotificationNoConnexion" method.
Any idea why ?
EDIT :
Using Firebug, I get this
Do you think the problem could be that "date" contain "17%2F02%2F2016" instead of "17/02/2016" ?
EDIT2 : One of the problem was the string format. I changed it to "02/17/2016" but still not working.
You are defining your content type as contentType: 'application/json',
and then send data as simple text.
You should remove so that jquery uses the default 'application/x-www-form-urlencoded; charset=UTF-8' type.
You have to send the date in ISO 8601 format, then the MVC modelbinder can bind it.
var GlobalJsHelpers = GlobalJsHelpers || {};
/// <summary>
/// Takes a utc js date and converts it to a iso8601 utc string
/// </summary>
GlobalJsHelpers.Iso8601FromUtc = function(utcDate) {
//create a two digit month string (01-12)
var month = ('0' + (utcDate.getUTCMonth() + 1)).substr(-2);
//create a two digit day string (01-31)
var day = ('0' + utcDate.getUTCDate()).substr(-2);
return utcDate.getUTCFullYear() + '-' + month + '-' + day;
};
Usage:
data: {'date' : GlobalJsHelpers.Iso8601FromUtc(dateValueInUtc)}

How do I parse Url with `&` sign in jquery code?

I have following code in common.js file.
logic is if HighlightTextBox if data is not matching and RemoveHighlightTextBox if data is matching.
url = /Services/GetAutoCompleteData?v=
name = My & Son
actualUrl = /Service/GetData?v=My & Son&eq=true
//debuge following js code and found above values
//here problem is because of `&` sign url gets disturb as `actualUrl is /Service/GetData?v=My & Son&eq=true`
//so after `&` sign url gets ignore by js (i.e Son&eq=true code)
//i have passes values `My & Son` but actually js parsing it as `My` so how do I parse my original URL with `&` sign ?
var div = $(this).closest("div");
var elem = div.find(":text");
elem.change();
var name = elem.val();
var actualUrl = url + name + "&eq=true"
var filter = $(this).attr("filter");
if (name == "") {
div.find(":hidden").val('');
return;
}
AjaxPostCall(actualUrl, filter, function (data) {
if (data == null || data.length != 1) {
HighlightTextBox(elem);
div.find(":hidden").val('');
return;
}
RemoveHighlightTextBox(elem)
div.find(":hidden").val(data[0].Key);
elem.val(data[0].Value);
});
function AjaxPostCall(actualUrl, extraParam, onSuccess) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: actualUrl,
data: extraParam,
dataType: "json",
success: function (data) { if (onSuccess != null) onSuccess(data); },
error: function (result) { }
});
}
Try this
var actualUrl = encodeURIComponent(url + name + "&eq=true");
encodeURIComponent Thisfunction encodes a URI component.
This function encodes special characters. In addition, it encodes the
following characters: , / ? : # & = + $ #
You need to escape the parameter value with & using method encodeURIComponent() before appending to parameter string.
ex
encodeURIComponent('name = My & Son')

Pairs key=value are splitting by each symbol code when Ajax call

Can't understand why my key=value pairs transform into symbols and in my ajax GET call I have:
GET /admin_schedule/get_schedule_db/?0=%5B&1=o&2=b&3=j&4=e&5=c&6=t&7=+&8=O&9=b&10=j&11=e&12=c&13=t&14=%5D&15=%22&16=%26&17=t&18=e&19=a&20=c
Instead of:
GET /admin_schedule/get_schedule_db/?teacherArray[]=128&teacherArray[]=134...
My code:
var eventss = '';
$("input[type='checkbox'][name='teacher']").each( function() {
if(this.checked) {
eventss += "&teacherArray[]=" + $(this).attr("value");
}
});
events1.data += eventss;
ajax for fullcalendar eventSources:
var events1 = {
url: '/admin_schedule/get_schedule_db/',
type: 'GET',
data: {sch_teacher_id: (sch_teacher_id) ? sch_teacher_id : $('.teacher').val() },
success: function (response) {
return response;
}
};
And then fetch fullcalendar with events
eventSources: [
events1,
events2,
events3
],
Concatenating a string with an object is almost never a good idea as Object#toString always returns "[object Object]". Unless you override toString in your object, the object is cast to string as this string (meaning its content is lost) before it's concatenated. Moreover, the resulting string is not a valid query string.
Instead of
eventss += "&teacherArray[]=" + $(this).attr("value");
...
events1.data += eventss;
try creating an empty teacherArray in data and
events1.data.teacherArray.push($(this).attr("value"));
Also consider using $("#my-form").serialize()
I solved this problem! (thx Jan Dvorak for your comments!).
1. variable now is an array:
var sch_teacher_id = new Array("<?php echo $sch_teacher_id; ?>");
2. empty the array each time before loop:
$('.teacher').change(function (event) {
events1.data.sch_teacher_id = [];
events2.data.sch_teacher_id = [];
events3.data.sch_teacher_id = [];
if($(this).val()) {
$("input[type='checkbox'][name='teacher']").each( function() {
if(this.checked) {
events1.data.sch_teacher_id.push($(this).attr("value"));
events2.data.sch_teacher_id.push($(this).attr("value"));
events3.data.sch_teacher_id.push($(this).attr("value"));
}
});
}
$calendar.fullCalendar('refetchEvents');
});

Categories