Error when laoding datatable from JSON - javascript

I'm developing a project where I fill an HTML table using datatables and a JSON returned from my server, which originally is a list of a class.
The code is the following one for each element:
Table HTML:
<table id="tablaDetalle2" class="display" role="grid" aria-describedby="example2_info">
<thead>
<tr>
<th>id</th>
<th>idFlight</th>
<th>idSample</th>
<th>import</th>
</tr>
</thead>
<tbody>
</table>
Javascript:
$('#tablaDetalle2').DataTable({
"bProcessing": true,
"sAjaxSource": "#Url.Action("Detalle","Muestra", new {idExp = 1, descrExp="abc"})"
});
ServerCode:
public ActionResult Detalle(int idExp, string descrExp)
{
List<Models.Muestra_Detalle> aaData = new List<Models.Muestra_Detalle>(); //Returns a list of the data
aaData = Manager.MuestraManager.Cargar_Detalle(idExp);
var jsonSerializer = new JavaScriptSerializer();
var JsonFinal = jsonSerializer.Serialize(aaData);
try
{
return Json(new { JsonFinal }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{ return null; }
}
The object JsonFinal returned has the following structure:
[{"id":"1","idFlight":1,"idSample":3217.5,"import":0}]
But I get the following error:
Unhandled exception at line 188, column 47 in
http://localhost:61298/Content/DataTables/jquery.dataTables.min.js
0x800a138f - JavaScript runtime error: Unable to get property 'length' of undefined or null reference
For instance, if I declare a hardcoded variable:
var data = new[] { "id:A", "idFlight:B", "idSample:C", "import:D" };
No error shows up, even though the content defined in the variable data and how it's shown in the table doesn't match.
I've tried so many ways to do it, some says it's just no data to show in the table, this seems the best possible approach once the issue is solved.
The biggest difference when hardcoding a the variable returned to the datatables is that the variable data is an object with 4 different strings, and the result of using JsonSerializer It's just like one string, I don't really know.
ÛPDATE
Renamed the JsonFinal to aaData, some error different pops ups, will try what some of you said and report back with more details.
New code from the server:
public ActionResult Detalle(int idExp, string descrExp)
{
ViewBag.Exp = descrExp;
List<Models.Muestra_Detalle> azaData = new List<Models.Muestra_Detalle>();
aaData = Manager.MuestraManager.Cargar_Detalle(idExp);
var jsonSerializer = new JavaScriptSerializer();
var aaData = jsonSerializer.Serialize(azaData);
//string data2 = JsonFinal.Replace("\\", "");
//var data = new[] { "id:A", "idgasto:B", "ImpGasto:C", "idMuestra:D" };
return Json(new { aaData }, JsonRequestBehavior.AllowGet);
}
New error : DataTables warning: table id=tablaDetalle2 - Requested unknown paramter 'id' for row 0, column 0. For more information about this error, please see https://datatables.net/tn/4.
Already went over there, couldnt get anything out.
It's like it can't find the column id in the returned JSON as it becomes null in the table.

Try returning your json object directly without using serializer. For example
public ActionResult Detalle(int idExp, string descrExp)
{
List<Models.Muestra_Detalle> aaData = new List<Models.Muestra_Detalle>(); //Returns a list of the data
aaData = Manager.MuestraManager.Cargar_Detalle(idExp);
try
{
return Json(aaData , JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{ return null; }
}

Alright, I still don't render the table correctly based on the JSON information but I managed to solve the issue....
The method I'm using sAjaxSource must return the object JSON from the server side named as aaData, now I have a problem as no matter what I send to the client, it will always take the first column with the value " and the rest of columns as null, but will ask another question for that.

Related

Why is getFields() returning an empty object?

I am working on a Google Data Studio community connector, and I am trying to display only one field to start with. All of the code is in the code.gs file, except getAuthType() and isAdminUser() is in Auth.gs.
The issue is that once getData() is called, getFields() returns an empty object. Here is the log:
It looks like getSchema() is working correctly, here is the log from that function:
Here is the getFields() function:
function getFields() {
var fields = cc.getFields();
var types = cc.FieldType;
fields
.newDimension()
.setId('device')
.setName('Device')
.setType(types.TEXT);
return fields;
}
Here is getData():
function getData(request){
console.log('getData request', request);
request.configParams = validateConfig(request.configParams);
console.log('getFields()', getFields(), typeof getFields());
var requestedFields = getFields().forIds(
request.fields.map(function(field){
return field.name;
})
);
try{
console.log('start request');
var apiResponse = fetchDataFromApi(request);
var data = formatData(apiResponse, requestedFields);
}catch (e){
cc.newUserError()
.setDebugText('Error fetching data from API. Exception details: ' + e)
.setText(
'The connector has encountered an unrecoverable error. Please Try again later.'
)
.throwException();
}
return {
schema: requestedFields.build(),
rows: data,
}
}
getSchema():
function getSchema(request){
var schema = {schema: getFields().build()};
console.log(schema);
return schema;
}
The community connector is initialized outside of all functions in the same file:
var cc = DataStudioApp.createCommunityConnector();
I looked through the documentation, but I cannot find anything that would cause getFields() to return an empty object, based off what I have. Any thoughts?
I thought that getFields() returning an empty object was causing my app to display the fields incorrectly, but the issue was that the data I was passing to the app was in the incorrect format.
getFields() isn't useful until it is called with build() (i.e. getFields().build() )
I think it is expected behavior to receive an empty object for getFields() alone.

JSON.parse(...).forEach is an error on published website

i'm currently working with rendering some graphs on a web mvc project. The graphs already render on my machine when i'm debugging the code, but the moment I publish it on the IIS of my QA server, I get the following error on console
TypeError: JSON.parse(...).forEach is not a function
Here's the a snippet of the code I'm currently working
ajaxPostConstancy.done(function (html) {
Utils.Alerts.HideGif();
var data = {};
var category = [];
var colors = [];
JSON.parse(html).forEach(function (e) {
category .push(e.date);
colors.push(e.color);
data[e.date] = e.data1;
})
....
any ideas of what's going on?
Edit: the html var inside the JSON.parse is te string returned by this code
public async Task<string> GetCompositionGraph(string contract, string methodName)
{
string preFormat = null;
try
{
string method = _configuration["Position:method:" + methodName];
PositionBL _bl = new PositionBL(Request, Response, _baseUri, method);
object model = await _bl.PostCompositionGraph(contract);
preFormat = JsonConvert.SerializeObject(model);
}
catch(Exception ex)
{
ViewBag.error = ex.Message;
}
return preFormat;
}
edit 2: the content of html variable which is generated by the code on the first edit:
html content:
[{"color":"#162ECB","date":"20","data1":1122954.8708},{"color":"#E03473","date":"00","data1":1323061.6168},{"color":"#CE029D","date":"26","data1":29982.2271}]
and this picture is the result I get from the JSON.parse when I debug my website
Edit 3: Visual input
The explorer console when the sites is deployed on my localhost for debugging
The explorer console while checking the site published on QA server
Edit 4: So i narrowed it down to the fact that the error comes when I debug the websit in Release mode, so that's kind of a step foward
If preformat returns null or an object forEach() will throw an error.
ajaxPostConstancy.done(function (html) {
Utils.Alerts.HideGif();
var data = {};
var category = [];
var colors = [];
var parsedDatas = JSON.parse(html)
if (Array.isArray(parsedDatas)) {
parsedDatas.forEach(function (e) {
// logic here
});
} else {
console.warn('This is not an array : ', html)
}
...
The forEach() method calls a function once for each element in an array while the JSON.parse() makes the html an object.

How to set root name of JavaScript object dynamically from controller using c#

The closest I have come to finding an an answer is here: https://stackoverflow.com/a/16295052/608674
The problem is that I can not figure out how set the root name dynamically.
Using the w3widget responsive-calendar. The calendar uses a javascript object with many child objects. Like this:
$(".responsive-calendar").responsiveCalendar({
events: {
"2018-04-30": {
"number": 5,
"badgeClass": "badge-warning",
"url": "http://w3widgets.com/responsive-calendar"
},
"2018-04-25": {
"number": 1,
"badgeClass": "badge-warning",
"url": "http://w3widgets.com/responsive-calendar"
},
"2018-04-03": {
"class": "active special",
"url": "http://w3widgets.com/responsive-calendar"
},
"2018-04-26": {
"number": 2,
"badgeClass": "badge-warning",
"url": "http://w3widgets.com"
},
"2018-05-03": {
"number": 1,
"badgeClass": "badge-error"
},
"2018-06-12": {}
}
});
I attempted to bypass this problem by returning a list of strings from the controller but this isn't working... I'm not sure how to add each string into the "event" JavaScript object with the correct root name.
var jsonEvent = string.Format("'{0}: {{'" +
"'class' : '{1}'," +
"'link' : '{2}'," +
"'link_target' : '{3}," +
"'title' : '{4}'," +
"'location' : '{5}'," +
"'date' : '{6}'," +
"'desc' : '{7}'," +
"'count' : '{8}'," +
"'event_id' : '{9}'" +
"}},",
evnt.StartDate.AddDays(i).ToString("yyyy-MM-dd"),
GetEventClass(evnt.Id, i, dayCount),
evnt.EventUrl,
hasLink,
evnt.Name,
evnt.Location,
dateString,
evnt.Description,
i,
eventId);
I tried to put the string into the event variable like this:
var actionUrl = '#Url.Action("GetJsonEvents", "EventsSurface", new { pageId = Model.Id })';
$.getJSON(actionUrl).done(function (data) {
$.each(data.items, function (index, item) { event[index] = value; });
});
Of course that seems wrong because it would give the root name the value of index.
I've also tried adding the data into variable called "events_data" and parsing it out like was suggested in another question events: Json.Parse(events_data), but that doesn't seem to work... probably because I'm not returning the data correctly from the controller.
It's apparent to me that I just don't understand this process well enough. I know I'm not working with JSON objects so that confuses me when trying to pass back data to the view from the controller...
Assuredly, part of the problem is that I am returning the list of strings from the controller like this: return Json(eventList, JsonRequestBehavior.AllowGet);
I don't know how else to return the data to an ajax call and place it into a JavaScript object.
Edit: 1/518 12.32
Using a Dictionary object in the controller works. I had to create a class for the Json Event Object because the name "class" is reserved in C# and I couldn't use an anonymous object. I ran into a problem trying to decorate the class property with a JsonProperty attribrute...
private class JsonEvent
{
[JsonProperty (PropertyName = "class")]
public string Class { get; set; }
public string link { get; set; }
...}
because I was still using the return Json(..., ...), which is the .net serialization not Newtonsoft. I just had to serialize using Json and return the content: return Content(JsonConvert.SerializeObject(eventList), "application/json");.
In the view, when I JSON.stringify(data) the event object looks perfect. Unfortunately, when I try to use the data in the resonsponive-calendar, it still doesn't work.
So far I have tried:
event_data = data;
event_data = JSON.stringify(data);
Whole ajax call looks like:
var events_data = {};
$.getJSON(actionUrl, events_data).done(function (data) {
console.log(JSON.stringify(data));
events_data = Json.parse(data);
});
And of course, the calendar just calls the event: events_data
Solved 1/5/18 13.54
So, yes, the dictionary in the Controller is the way to go. I am working with someone else's code in JavaScript. They hardcoded the data in. Turns our that the calendar was loading and calling the event data before the ajax call was complete.
so events_data = data works just fine.
Have you tried passing a dictionary from the controller? If that doesn't work, you might have to use a classic ASHX handler and ResponseWrite the JSON object to do what you want.
I'm not sure if returning a Dictionary<string, event> where the date string is the key, from a controller would do what you want or not, but it would be worth a try. JSON isn't hard to ResponseWrite from generic handler either though.

Return list to JSON to Angularjs

It is such that I must have sent some content from my controller over to Angularjs which shall come forth with words such as only L in themselves or E, so it goes in other words, of words where it like just let the words sign which has the single letter.
There is no fault forward by the console and what I believe is the problem is that it does not specify any value to the side.
i have try its here:
A circular reference was detected while serializing an object of type 'SubSonic.Schema .DatabaseColumn'.
Load.js
var app = angular.module('WordSpreads',[]);
app.controller('WordSpreadsListValue', function ($scope, $http) {
$http(
{
method: 'GET',
url: '../Profile/MWordSpreads'
}).success(function (response) {
$scope.entries = data.List;;
});
console.log("TEST");//It does not appear in the console log.
});
Controller:
[HttpGet]
public JsonResult MWordSpreads()
{
WordsSpreadsListValue model = new WordsSpreadsListValue();
var db = HelperToTables.DbValue;
model.List = db.WordSpreads.ToList();
return Json(model.List, JsonRequestBehavior.AllowGet);
}
Model:
public class WordsSpreadsListValue
{
public List<WordSpread> List { get; set; }
}
Error giv me:
A circular reference was detected while serializing an object of type
'xxSitename.Models.LinqDatabase.WordSpread'
UPDATE:
model.List = db.WordSpreads.Select(x => new {
Name = x.name,
TextValue = x.text.ToString()
}).ToList();
ERROR :
Cannot implicitly convert type
'System.Collections.Generic.List<>' to
'System.Collections.Generic.List' MVCOrdklar2015
.
model.List = db.WordSpreads.Select(x => new { Prop1 = x.1, Prop2 = x.2}).ToList();
You are having trouble serializing model.List, the Json serialize is barfing on serializing model.List. If you make it a new object without navigation properties you will be fine.
In my experience it has to do with the navigation properties, I dont fully understand what it is. But, once you remove the navigation properties from the equation it will work.

Laravel Datatables empty collection error

I'm using Laravel Datatables package to show Ajaxified tables.
I'm getting an error when the collection i want to show in my table is empty, the error is:
ErrorException in CollectionEngine.php line 46: array_keys() expects
parameter 1 to be array, null given
My controller contains two simple functions
// get the view
public function getItems() {
return view('someview');
}
// get data for datatables
public function getItemsdata() {
$data = DataModel::all();
return Datatables::of($data)->make(true);
}
When $data is not empty, everything works just fine but if it is empty, I get the error! how can i fix this? any ideas?
I think you can use the isEmpty() function of laravel
public function getItemsdata() {
$data = DataModel::all();
if($data->isEmpty()){ //I think laravel has isEmpty() function
return 'error!'; //throw exception here
}else{
return Datatables::of($data)->make(true);
}
}

Categories