Share via


Uncaught TypeError: Cannot read property 'length' of undefined

Question

Friday, November 1, 2019 5:08 AM

Hi

  I am getting below error

Uncaught TypeError: Cannot read property 'length' of undefined
    at xb (jquery.dataTables.min.js:39)
    at jquery.dataTables.min.js:37
    at i (jquery.dataTables.min.js:35)
    at Object.success (jquery.dataTables.min.js:35)
    at fire (jquery-1.10.2.js:3062)
    at Object.fireWith [as resolveWith] (jquery-1.10.2.js:3174)
    at done (jquery-1.10.2.js:8249)
    at XMLHttpRequest.callback (jquery-1.10.2.js:8792)


$(document).ready(function () {
    $("#tblUser").DataTable({
        "lengthMenu": [3, 5, 10],
        "processing": true, // for show progress bar
        "serverSide": true, // for process server side
        "filter": false, // this is for disable filter (search box)
        "orderMulti": false, // for disable multiple column at once
        
        "ajax": {
            //"url": "@Url.Content("~/Users/GetAllUsers")",
            "url": "/Home/List",
            "type": "GET",
            "datatype": "json"
        },
        "columns": [
                { "data": "UserName", "name": "UserName", "autoWidth": true },
                { "data": "Password", "name": "Password", "autoWidth": true },
                { "data": "FirstName", "name": "FirstName", "autoWidth": true },
                { "data": "LastName", "name": "LastName", "autoWidth": true }
        ]
    });
});

public class HomeController : Controller
    {
        UserDb usrDB = new UserDb();
        public ActionResult Index()
        {
            return View();
        }
        public JsonResult List()
        { 
            //ViewBag.CurrentPage = 1;
            //ViewBag.LastPage = Math.Ceiling(Convert.ToDouble(db.Manufacturers.ToList().Count) / 5);
            //return View(db.Manufacturers.Take(5));
            return Json(usrDB.GetAllUser(), JsonRequestBehavior.AllowGet);
        }
        public JsonResult AddUser(User Usr)
        {
            return Json(usrDB.AddUser(Usr), JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetbyName(string UsrName)
        {   
            var UserName = usrDB.GetAllUser().Find(x => x.UserName.Equals(UsrName));
            return Json(UserName, JsonRequestBehavior.AllowGet);
        }
        public JsonResult UpdateUser(User Usr)
        {
            return Json(usrDB.UpdateUser(Usr), JsonRequestBehavior.AllowGet);
        }
        public JsonResult DeleteUser(string UsrName)
        {
            return Json(usrDB.DeleteUser(UsrName), JsonRequestBehavior.AllowGet);
        }
    }  

Thanks

All replies (9)

Friday, November 1, 2019 7:15 AM

Hi jsshivalik,

I think we have discussed this problem at Uncaught TypeError, it should have been solved, have you tried the solution i provided? Or are you meeting other error after you tried the solution?

You can check below demo built based on your code using the solution i provided in the last thread which solved the problem:

cshtml:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>DatatableLengthDemo</title>
    <script src="~/Scripts/jquery-3.3.1.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
    <script>
        $(document).ready(function () {
    $("#tblUser").DataTable({
        "lengthMenu": [3, 5, 10],
        "processing": true, // for show progress bar
        "serverSide": true, // for process server side
        "filter": false, // this is for disable filter (search box)
        "orderMulti": false, // for disable multiple column at once

        "ajax": {
            "url": "/Demo/List",
            "type": "GET",
            "datatype": "json"
        },
        "columns": [
                { "data": "UserName", "name": "UserName", "autoWidth": true },
                { "data": "Password", "name": "Password", "autoWidth": true },
                { "data": "FirstName", "name": "FirstName", "autoWidth": true },
                { "data": "LastName", "name": "LastName", "autoWidth": true }
        ]
    });
});
    </script>
</head>
<body>
    <div>
        <table id="tblUser"></table>
    </div>
</body>
</html>

controller:

public ActionResult DatatableLengthDemo()
        {
            return View();
        }

public JsonResult List()
        {
            List<user> list = new List<user>();
            list.Add(new user() { UserName = "aa", Password = "123",FirstName="a",LastName="a" });
            list.Add(new user() { UserName = "bb", Password = "123", FirstName = "b", LastName = "b" });
            list.Add(new user() { UserName = "cc", Password = "123", FirstName = "c", LastName = "c" });

            return Json(new { data = list }, JsonRequestBehavior.AllowGet);
        }

        public class user
        {
            public string UserName { get; set; }
            public string Password { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }

All you need to do is to change the return Json(usrDB.GetAllUser(), JsonRequestBehavior.AllowGet); in your code to return Json(``new { data = usrDB.GetAllUser()}``, JsonRequestBehavior.AllowGet);.

Best Regard,

Yang Shen


Friday, November 1, 2019 7:23 AM

Hi

   I have below code. What changes should i made now

public List<User> GetAllUser()
{
connection();
List<User> UserList = new List<User>();

SqlCommand com = new SqlCommand("Users", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("@Action", "Select");
SqlDataAdapter da = new SqlDataAdapter(com);
DataTable dt = new DataTable();

con.Open();
da.Fill(dt);
con.Close();

foreach (DataRow dr in dt.Rows)
{
UserList.Add(
new User
{
UserName = Convert.ToString(dr["UserName"]),
Password = Convert.ToString(dr["Password"]),
FirstName = Convert.ToString(dr["FirstName"]),
LastName = Convert.ToString(dr["LastName"]),
}
);
}
return UserList;
}

Thanks


Friday, November 1, 2019 7:55 AM

Hi jsshivalik,

I think in this situation, a better practice would be using SqlDataReader instead of SqlDataAdapter.

You can refer to below demo and i will highlight the place i updated than the demo in my ealier post:

cshtml:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>DatatableLengthDemo</title>
    <script src="~/Scripts/jquery-3.3.1.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
    <script>
        $(document).ready(function () {
    $("#tblUser").DataTable({
        "lengthMenu": [3, 5, 10],
        "processing": true, // for show progress bar
        "serverSide": true, // for process server side
        "filter": false, // this is for disable filter (search box)
        "orderMulti": false, // for disable multiple column at once

        "ajax": {
            "url": "/Demo/List",
            "type": "GET",
            "datatype": "json"
        },
        "columns": [
                { "data": "UserName", "name": "UserName", "autoWidth": true },
                { "data": "Password", "name": "Password", "autoWidth": true },
                { "data": "FirstName", "name": "FirstName", "autoWidth": true },
                { "data": "LastName", "name": "LastName", "autoWidth": true }
        ]
    });
});
    </script>
</head>
<body>
    <div>
        <table id="tblUser"></table>
    </div>
</body>
</html>

controller:

public ActionResult DatatableLengthDemo()
        {
            return View();
        }

public JsonResult List()
        {
            return Json(new { data = GetAllUser() }, JsonRequestBehavior.AllowGet);
        }

        public List<Users> GetAllUser()
        {
            List<Users> UserList = new List<Users>();
            using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DatabaseTestPool;Integrated Security=True"))
            {
                conn.Open();
                SqlCommand com = new SqlCommand("UsersSP", conn);
                com.CommandType = CommandType.StoredProcedure;
                com.Parameters.AddWithValue("@Action", "Select");
                SqlDataReader sdr = com.ExecuteReader();
                if (sdr.HasRows)
                {
                    while (sdr.Read())
                    {
                        UserList.Add(new Users() { UserName = sdr["UserName"].ToString(), Password = sdr["Password"].ToString(), FirstName = sdr["FirstName"].ToString(), LastName = sdr["LastName"].ToString() });
                    }
                }
            }
            return UserList;
        }

        public class Users
        {
            public string UserName { get; set; }
            public string Password { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }

sql:

create table User4Test
(
UserName varchar(50),
Password varchar(50),
FirstName varchar(50),
LastName varchar(50),
)

insert into User4Test values('aa','123','a','a')
insert into User4Test values('bb','123','b','b')
insert into User4Test values('cc','123','c','c')
insert into User4Test values('dd','123','d','d')
insert into User4Test values('ee','123','e','e')

create proc UsersSP
@Action varchar(50)
as
if @Action='Select'
begin
select * from User4Test
end

And below is the result:

Hope this could help.

Best Regard,

Yang Shen


Saturday, November 2, 2019 8:30 AM

Hi Yang

   3 is selected in Dropdown but it is showing 5. Secondly Showing o of 0 of 0 entries is also wrong

Thanks


Monday, November 4, 2019 1:25 AM

Hi jsshivalik,

I'm so sorry haven't seen this problem in time.

Please remove the "serverSide": true, in your DataTable settings which you can refer to Showing 0 to 0 of 0 entries (filtered from NaN total entries).

<script>
        $(document).ready(function () {
            $("#tblUser").DataTable({
                "lengthMenu": [3, 5, 10],
                "processing": true, // for show progress bar
                //"serverSide": true, // for process server side
                "filter": false, // this is for disable filter (search box)
                "orderMulti": false, // for disable multiple column at once

                "ajax": {
                    "url": "/Demo/List",
                    "type": "POST",
                    "datatype": "json"
                },
                "columns": [
                    { "data": "UserName", "name": "UserName", "autoWidth": true },
                    { "data": "Password", "name": "Password", "autoWidth": true },
                    { "data": "FirstName", "name": "FirstName", "autoWidth": true },
                    { "data": "LastName", "name": "LastName", "autoWidth": true }
                ]
            });
        });
    </script>

Below is the result of current demo:

Best Regard,

Yang Shen


Monday, November 4, 2019 8:31 AM

Hi Yang

  Still getting same error

$(document).ready(function () {
    $("#tblUser").DataTable({
        "lengthMenu": [3, 5, 10],
        "processing": true, // for show progress bar
        //"serverSide": true, // for process server side
        "filter": false, // this is for disable filter (search box)
        "orderMulti": false, // for disable multiple column at once
        "ajax": {
            //"url": "@Url.Content("~/Users/GetAllUsers")",
            "url": "/Home/List",
            "type": "POST",
            "datatype": "json"
        },
        "columns": [
                { "data": "UserName", "name": "UserName", "autoWidth": true },
                { "data": "Password", "name": "Password", "autoWidth": true },
                { "data": "FirstName", "name": "FirstName", "autoWidth": true },
                { "data": "LastName", "name": "LastName", "autoWidth": true }
        ]
    });


<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/DataTables/css/jquery.dataTables.min.css" rel="stylesheet" />
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">

<script src="~/Scripts/jquery-1.10.2.js"></script>  
<script src="~/Scripts/bootstrap.js"></script>  
<script src="~/scripts/DataTables/jquery.dataTables.min.js"></script>
<script src="~/Scripts/User.js"></script> 
<script src="~/scripts/jquery-ui-1.10.0.min.js"></script>
<div class="container">  

    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" onclick="clearTextBox();">Add New User</button><br /><br />  
    <table id="tblUser" class="table table-striped table-bordered dt-responsive nowrap" width:"100%" cellspacing="0" >  
        <thead>  
            <tr>  
                <th>  
                    UserName 
                </th>  
                <th>  
                    Password  
                </th>  
                <th>  
                    FirstName  
                </th>  
                <th>  
                    LastName  
                </th>  
                <th>
                    Action
                </th>
            </tr>  
        </thead>  
        <tbody class="tbody">  
  
        </tbody>  
    </table>  
</div>  

public class HomeController : Controller
    {
        UserDb usrDB = new UserDb();
        public ActionResult Index()
        {
            return View();
        }
        public JsonResult List()
        { 
            //ViewBag.CurrentPage = 1;
            //ViewBag.LastPage = Math.Ceiling(Convert.ToDouble(db.Manufacturers.ToList().Count) / 5);
            //return View(db.Manufacturers.Take(5));
            return Json(usrDB.GetAllUser(), JsonRequestBehavior.AllowGet);
        }
        public JsonResult AddUser(User Usr)
        {
            return Json(usrDB.AddUser(Usr), JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetbyName(string UsrName)
        {   
            var UserName = usrDB.GetAllUser().Find(x => x.UserName.Equals(UsrName));
            return Json(UserName, JsonRequestBehavior.AllowGet);
        }
        public JsonResult UpdateUser(User Usr)
        {
            return Json(usrDB.UpdateUser(Usr), JsonRequestBehavior.AllowGet);
        }
        public JsonResult DeleteUser(string UsrName)
        {
            return Json(usrDB.DeleteUser(UsrName), JsonRequestBehavior.AllowGet);
        }
    }  

public List<User> GetAllUser()
{
connection();
List<User> UserList = new List<User>();

SqlCommand com = new SqlCommand("Users", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("@Action", "Select");
SqlDataAdapter da = new SqlDataAdapter(com);
DataTable dt = new DataTable();

con.Open();
da.Fill(dt);
con.Close();

foreach (DataRow dr in dt.Rows)
{
UserList.Add(
new User
{
UserName = Convert.ToString(dr["UserName"]),
Password = Convert.ToString(dr["Password"]),
FirstName = Convert.ToString(dr["FirstName"]),
LastName = Convert.ToString(dr["LastName"]),
}
);
}
return UserList;
}

Thanks


Monday, November 4, 2019 8:51 AM

Hi jsshivalik,

As i mentioned at the beginning, you have to return the correct format of value:

public JsonResult List()
        { 
            //ViewBag.CurrentPage = 1;
            //ViewBag.LastPage = Math.Ceiling(Convert.ToDouble(db.Manufacturers.ToList().Count) / 5);
            //return View(db.Manufacturers.Take(5));
            return Json(usrDB.GetAllUser(), JsonRequestBehavior.AllowGet);
        }

This part should be modified like below:

public JsonResult List()
        {
            return Json(new { data = usrDB.GetAllUser() }, JsonRequestBehavior.AllowGet);
        }

Please try again now, it should be fixed.

Best Regard,

Yang Shen


Monday, November 4, 2019 9:55 AM

Hi Yang

  Thanks . What is the purpose of new word. secondly i want to know if i comment //"serverSide": true, // for process server side

then it works fine why so

$(document).ready(function () {
    $("#tblUser").DataTable({
        "lengthMenu": [3, 5, 10],
        "processing": true, // for show progress bar
        //"serverSide": true, // for process server side
        "filter": false, // this is for disable filter (search box)
        "orderMulti": false, // for disable multiple column at once
        "ajax": {
            //"url": "@Url.Content("~/Users/GetAllUsers")",
            "url": "/Home/List",
            "type": "POST",
            "datatype": "json"
        },
        "columns": [
                { "data": "UserName", "name": "UserName", "autoWidth": true },
                { "data": "Password", "name": "Password", "autoWidth": true },
                { "data": "FirstName", "name": "FirstName", "autoWidth": true },
                { "data": "LastName", "name": "LastName", "autoWidth": true }
        ]
    });

});

Thanks


Tuesday, November 5, 2019 1:55 AM

Hi jsshivalik,

What is the purpose of new word.

The ajax has to return a new data object so that the datatable can discriminate the value as the format in its "columns" to show. Just remember it as a fixed format.

You can debug the program and see the Jsonresult it returns:

secondly i want to know if i comment //"serverSide": true, // for process server side

then it works fine why so

The serverSide:true, means the filtering, paging and sorting calculations are all performed by a server. It will conflict with your current code.

For more information about this property, please refer to serverSide and Server-side processing.

Hope the explanation is clear and if so you can mark it as answer.

For more problems, you are willing to open new threads.

Best Regard,

Yang Shen