DataTables: Cannot read property 'length' of undefined, but the JSON is valid - datatables

var deptTable = $('#team-table').DataTable( {
"ajax": "/cc/AjaxDashboard/getMyTeam",
"pageLength": 10,
"scrollY": "250px"
});
I have this. The JSON response is just [] as there's no data. I am getting:
Cannot read property 'length' of undefined
I thought [] was valid JSON as per https://jsonlint.com/ and it would show an empty message but I get an error instead

[] is indeed a valid JSON syntax for empty array. The reason you're getting the error is because the data returned from your AJAX doesn't match the DataTable's default expectation.
There are 3 ways you can use with the ajax option:
Give it a string as the AJAX source
Give it a configuration object
Give it a function
And by default, when the AJAX source is given, DataTables expects the returned data to be an array of items with the key data:
{
data: []
}
If your AJAX doesn't return this format, you will get that error. Here is the proof: https://jsfiddle.net/davidliang2008/s2xgof6t/22/
To fix it, you can override the returned format by setting dataSrc to an empty string, like this:
{
ajax: {
url: xxx,
dataSrc: ''
}
}
demo: https://jsfiddle.net/davidliang2008/s2xgof6t/26/
More reads on this custom data source property: https://datatables.net/examples/ajax/custom_data_property.html

Related

Cannot read property 'employee_name' of undefined

Im using Postman platform for testing API. I'm actually new to Postman. So, Currently testing dummy APIs, where i fetched the GET response result from the URI
http://dummy.restapiexample.com/api/v1/employees , when i add validation points :
specifying test description as "name" See below
var response = JSON.parse(responseBody);
tests["name"] = response.data[2].employee_name == "Ashton Cox";
Test operation successfully passed. But when using specific id in the URI link
http://dummy.restapiexample.com/api/v1/employee/5
with same validations points as above, i'm getting response as TypeError: Cannot read property 'employee_name' of undefined, below is the screenshot
The correct reference and syntax would look like this:
pm.test("Check User", () => {
const responseJson = pm.response.json();
pm.expect(responseJson.data.employee_name).to.eql("Airi Satou");
});

Setting custom field values on a card with the Trello API

I am trying to use the new Custom Fields methods of the Trello API to set the value of a custom field on a card.
I've created a custom field of type number. When I make a GET request for the custom field by it's id, it returns this custom field object:
{
"id":"5ab13cdb8acaabe576xxxxx",
"idModel":"54ccee71855b401132xxxxx",
"modelType":"board",
"fieldGroup":"837a643fd25acc835affc227xxxxxxxxxxxxxxxxxxxx",
"name":"Test Number Field",
"pos":16384,
"type":"number"
}
Then when I create a new card in the Trello UI (but do not type in a value in the Test Number Field box) and then GET that card using the customFieldItems=true (as documented here), it returns this card object (irrelevant fields removed):
{
"id": "5ab56e6b62abac194d9xxxxx",
"name": "test1",
"customFieldItems": []
}
Note that since I did not type anything into the Test Number Field box in the UI, the customFieldItems property contains an empty array.
Then if I type in the number 1 in the Test Number Field box in the UI and GET the card again, it returns this (irrelevant fields removed):
{
"id": "5ab56e6b62abac194d9xxxxx",
"name": "test1",
"customFieldItems":
[
{
"id": "5ab570c5b43ed17b2dxxxxx",
"value": {
"number": "1"
},
"idCustomField": "5ab13cdb8acaabe5764xxxxx",
"idModel": "5ab56e6b62abac194d9xxxxx",
"modelType": "card"
}
]
}
I want to be able to set the value of this custom field via API.
When I go to the API documentation for "Setting, updating, and removing the value for a Custom Field on a card," (here) I plug in the following information:
Query Auth
key: (our valid/working Trello API key)
token: (our valid/working Trello API token)
PATH PARAMS
idCard: (ID of the card that the Custom Field value should be set/updated for) 5ab56e6b62abac194d9xxxxx
idCustomField (ID of the Custom Field on the card.): 5ab570c5b43ed17b2dxxxxx
QUERY PARAMS
idCustomField (ID of the Custom Field to which the item belongs.): 5ab13cdb8acaabe576xxxxx
modelType (This should always be card.): card
value (An object containing the key and value to set for the card's Custom Field value. The key used to set the value should match the type of Custom Field defined.): {"number": 2}
When I click Try It, I get the response: 400 Bad Request "Invalid custom field item value."
I've tried the following things:
Switching the two idCustomField values (it's confusing that both the path parameter and query parameter have the same name, implying that they are meant to accept the same value, but then they have different descriptions, and the descriptions are vague/confusing).
Setting both idCustomField values to the same thing (for both of the possible IDs)
Setting the value to 2, {"number": "2"}, {number: 2}, {number: "2"} and more.
No matter what I try, I always get "Invalid custom field item value." This behaves the same way whether the card has a value in the custom field or not.
I'm pretty sure that the idCustomField in the path params is being accepted, because when I change one character, it gives me this error instead: "invalid value for idCustomField".
So I don't know if the "Invalid custom field item value." is referring to the query param idCustomField* or the value.
I also don't know if it makes a difference whether or not the card has an existing value in the custom field, but I want to be able to set the value of this custom field regardless of whether or not it currently has a value in the field.
The live example (using XMLHttpRequest) on the Trello documentation page is wrong. You should use the next example using fetch.
var url = "https://api.trello.com/1/cards/{idCard}/customField/{idCustomField}/item?token={yourToken}&key={yourKey}";
var data = {value: { number: "42" }};
fetch(url, { body: JSON.stringify(data), method: 'PUT', headers: {'content-type': 'application/json'}})
.then((resp) => resp.json())
.then((data) => console.log(JSON.stringify(data, null, 2)))
.catch((err) => console.log(JSON.stringify(err, null, 2)))
This example works. And after trying this, I modified the XMLHttpRequest version and it worked too.
var data = null;
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});
data = {value: { number: "3" }}; //added
var json = JSON.stringify(data); //added
xhr.open("PUT", 'https://api.trello.com/1/cards/{idCard}/customField/{idCustomField}/item?key={yourkey}&token={yourtoken}');
xhr.setRequestHeader('Content-type','application/json'); //added
xhr.send(json); //modified
The point is that you should 1) set the request Content-type header to application/json and 2) pass the value via JSON object body.
I tried to edit the live example on the documentation but I it was not possible. I hope they will fix it soon.

Component method response object data binding

I am starting to lose my mind in debugging an application that I inherited from a fellow developer who is absent.
I have narrowed down the problem to the following place in code (php files are checked, Vue instances are initialised, there are no syntax errors).
This is my the component that gets initialised:
var RadniStol = Vue.component('radnistol', {
template: '#template-RadniStol',
data() {
return {
tableData: [],
requestData: {
sort: "ID",
order: "DESC"
}
}
},
methods: {
reloadTable: function (event) {
data = this.requestData;
this.$http.post('php/get/radni_stol.php', data).then(response => {
console.log(response.data.bodyText);
this.tableData = response.data.records;
});
},
.
.
.
The PHP file that gets called with the POST method is working correctly, querying the database and echoing the response in a JSON format.
The thing that is making me pull out my hair is the following: the console.log(response.data) outputs the following into the console:
{"records":[{"DODAN_NA_RADNI_STOL":"1","..."}]}
It is an JSON object that I expected to have but when trying to assign it to the data of the component with:
this.tableData = response.data;
or any other way… response.data.records returns ‘undefined’ in the console. I have tryed with JSON.parse() but no success.
When logging types to console:
response variable is a response object with a status 200 and body and bodyText containing the data from the database.
response.data is a string type containing the string JSON with the data from the database.
When trying to use JSON.parse(response.data) or JSON.parse() on anything in the callback of the POST method I get the following error in the console:
RadniStol.js?version=0.1.1:17 Uncaught (in promise) SyntaxError: Unexpected token in JSON at position 0
at JSON.parse (<anonymous>)
at VueComponent.$http.post.then.response (RadniStol.js?version=0.1.1:17)
at <anonymous>
I am really starting to lose my mind over this issue, please help!
Thank you
If response.data is string, with JSON inside, then to access the records field, you should decode it like this:
JSON.parse(response.data).records
Not sure this has something to do with PHP or Vue.js, it is just plain javascript issue.
If it not decodes, than problem is definitely in response.data. For example
{"records":[{"DODAN_NA_RADNI_STOL":"1","..."}]}
is not a valid JSON, because key "..." needs to have some value.
But it seems to me that response.data is already parsed.
What I suggest you to do, is to write handler of the response as separate function, make response object that mimics actual response object by hand, and then test it separately from request. So you could show us request object and function that works with it.
I had the same error and fixed it.
Result will be response.body not response.data.
Here is my code:
getS: function(page) {
this.$http.get('vue-manager?page=' + page).then((response) => {
var data = JSON.parse(response.body);
this.student = data.data.data;
this.pagination = data.pagination;
});
},

Kendo UI autocomplete dynamically loading dBdata when typing

I am writing a kendo UI autocomplete widget. The requirement is EACH TIME when I type a letter after "minLength", the dataSource need to be dynamically loaded from dB EVERYTIME. One problem is that, when the dataSource load successfully in the first time, it stops loading data.
The code snippet is:
var data;
function getDataFromDb(){
// some code to grab dummyData from dB ...
return dummyData;
}
$("#someInputText").kendoAutoComplete({
minLength: 2,
dataTextField: "someField",
dataSource: getDataFromDb(),
filter: "startswith"
});
Thanks a lot.
More details on the post. In my situation, I don't use the readOption. The data comes from another ajax call like:
var data [];
//fire this ajax call when input string length comes to 4...
$.ajax({url: "some working url", success: function(result){
var data = result;
startKendoAutoComplete();
}
});
function startKendoAutoComplete(){
if( !$.isEmptyObject(data)) // set a breakPoint, have data
{
$("#inputText").kendoAutoComplete({
minLength: 4,
dataSource : data,
...
});
}
}
Also, the ajax call will be fired when the input string length comes to 4. However, the KendoAutoComplete doesn't start working....
Thanks a lot for your sugesstion.
If you init your dataSource with an array of object, your widget will work with this array only.
The first thing you'll have to create an dataSource object and set the serverFiltering property to true. Then, if you don't specify an url where the data will be fetched, you set you own transport.read function and from there you'll be able to implement your own logic. The read function will receive the readOption which will include all the relevant information to query tour data (top / skip / filter / sort ...). The readOptions will also provide a success function that should be used to return the value:
dataSource: {
serverFiltering: true,
transport: {
read: function (readOptions) {
readOptions.success(getDataFromDb(readOptions));
}
}
},

vue js returned value gives undefined error

i want to check the returned value of $http.get() but i get undefined value. Here is my vue js code:
var vm = new Vue({
el: '#permissionMgt',
data: {
permissionID: []
},
methods:{
fetchPermissionDetail: function (id) {
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
this.permissionID = data.permissionID; //permissionID is a data field of the database
alert(this.permissionID); //*****this alert is giving me undefined value
});
},
}
});
Can you tell me thats the problem here?.. btw $http.get() is properly fetching all the data.
You need to check what type is the data returned from the server. If #Raj's solution didn't resolve your issue then probably permissionID is not present in the data that is returned.
Do a colsole.log(data) and check whether data is an object or an array of objects.
Cheers!
Its a common js error. Make the following changes and it will work.
fetchPermissionDetail: function (id) {
var self = this; //add this line
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
self.permissionID = data.permissionID; //replace "this" with "self"
});
},
}
the reason is this points to window inside the anonymous function function()
This is a well known js problem. If you are using es2015 you can use arrow syntax (() => { /*code*/ }) syntax which sets this correctly