Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this function returning NaN?

At first this might seem to be like many of the other questions already asked regarding NaN in JavaScript, but I assure you it's not.

I have this piece of code that converts grabs the value from a textbox, and converts it into a date after clicking a button in a form:

var dateString = $('#itemAcquiredTxt').val(); //Would have a value of '2013-12-15'
var dateAcquired = new Date(dateString); //Invalid Date ?

The textbox itemAcquiredTxt would have a value of "2013-12-15" (YYYY-MM-DD format) taken from a database call:

$('#itemAcquiredTxt').val(new Date(item.DateAcquired).toLocaleDateString());

After creating the new Date object it gives me "Invalid Date".

OK... So I thought of making the Date object by passing it year, month and day as numbers - one of its other constructors.

 var year = Number(dateString.split("-")[0]); //Returns NaN
 var month = Number(dateString.split("-")[1]); //Returns NaN
 var day = Number(dateString.split("-")[2]); //Returns NaN
 var dateAcquired = new Date(year, month - 1, day); //InvalidDate

I tried splitting the string in the date textbox by the dash, and convert the string into a number using both Number and parseInt - but both gave me a NaN. I double checked the string values and nothing seemed wrong: "2013", "12", "15" on the split items respectively.

I said to myself...maybe my code is bad, and tried it on JSFiddle https://jsfiddle.net/jrxg40js/
But as you can see there, after placing a date in the text and pressing the button, it works!

Heres the relevant HTML code

<table id="inputTable">
            <tr>
                <td><span><strong>Name:</strong></span></td>
                <td><input id="itemNameTxt" type="text" value="" /></td>
            </tr>
            <tr>
                <td><span><strong>Category:</strong></span></td>
                <td>
                    <select id="categorySelect" ng-model="selectedCategory" ng-change="changeSubCategoryList(selectedCategory)" ng-options="cat as cat.CategoryName for cat in categoriesObj track by cat.CategoryID">
                        <option value="">---Please Select One---</option>
                    </select>
                </td>
            </tr>
            <tr ng-show="hasSubCat">
                <td><span><strong>Sub Category</strong></span></td>
                <td>
                    <select id="subCategorySelect">
                        <option value="">---Please Select One---</option>
                        <option ng-repeat="sub in subCategoryObj" value="{{sub.SubCatID}}">{{sub.SubCatName}}</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td><span><strong>Description:</strong></span></td>
                <td><input id="itemDescriptionTxt" type="text" value="" /></td>
            </tr>
            <tr>
                <td><span><strong>Serial Number:</strong></span></td>
                <td><input id="itemSerialNumberTxt" type="text" value="" /></td>
            </tr>
            <tr>
                <td><span><strong>Year:</strong></span></td>
                <td><input id="itemYearTxt" type="text" value="" /></td>
            </tr>
            <tr>
                <td><span><strong>Initial Cost:</strong></span></td>
                <td><input id="itemValueTxt" type="text" value="" /></td>
            </tr>
            <tr>
                <td><span><strong>Department:</strong></span></td>
                <td>
                    <select id="departmentSelect">
                        <option value="">---Please Select One---</option>
                        <option ng-repeat="dep in departmentsObj" value="{{dep.RoleID}}">{{dep.RoleDescription}}</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td><span><strong>Campus:</strong></span></td>
                <td>
                    <select id="campusSelect" ng-model="selectedCampus" ng-change="changeBuildingList(selectedCampus)" ng-options="campus as campus.CampusDescription for campus in campusesObj track by campus.CampusID">
                        <option value="">---Please Select One---</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td><span><strong>Building:</strong></span></td>
                <td>
                    <select id="buildingSelect">
                        <option value=""> </option>
                        <option ng-repeat="building in buildingsObj" value="{{building.BuildingID}}">{{building.BuildingDescription}}</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td><span><strong>Date Acquired:</strong></span></td>
                <td><input id="itemAcquiredTxt" type="text" value="" /></td>
            </tr>
            <tr>
                <td><span><strong>Notes:</strong></span></td>
                <td>
                    <textarea id="noteTxt"></textarea>
                </td>
            </tr>
        </table>

Relevant AngularJS function used to update the item with new data keyed by user - the function gets called when a user presses a confirmation button:

$scope.editItem = function () {
    var dateString = $('#itemAcquiredTxt').val();
    dateAcquired = new Date(dateString);
    var invItem = {
        ItemID: $('#itemID').val(),
        ItemName: $('#itemNameTxt').val().trim(),
        CategoryID: $('#categorySelect').find(":selected").val(),
        SubCategoryID: $('#subCategorySelect').find(":selected").val(),
        Description: $('#itemDescriptionTxt').val().trim(),
        SerialNumber: $('#itemSerialNumberTxt').val().trim(),
        Year: $('#itemYearTxt').val().trim(),
        DateAcquired: dateAcquired,
        Value: $('#itemValueTxt').val().trim(),
        RoleID: $('#departmentSelect').find(":selected").val(),
        Barcode: null,
        Notes: $('#noteTxt').val().trim(),
        Deleted: null,
        AddedBy: null,
        DateAdded: null,
        ModifiedBy: null, //Added by server
        DateModified: null,
        DeletedBy: '',
        DateDeleted: null,
        CampusID: $('#campusSelect').find(":selected").val(),
        BuildingID: $('#buildingSelect').find(":selected").val(),
        RoomID: null
    };
    $http.put("api/inventory/", invItem).success(function (data, status, headers, config) {
        inventoryData.retrieveData(); //On success, refresh zeh data
    }).error(function (data, status, headers, config) {
        console.log(data);
    });

    $("#dialogForm").dialog("close");

Why is my code returning NaN on my working environment (Visual Studio 2015 debugging on IE11) when other sites, such as JSFiddle is returning what I'm expecting?

like image 611
Cuauhtemoc Avatar asked Dec 15 '15 15:12

Cuauhtemoc


1 Answers

Fixed the problem - which really I have no idea what it even was.

The problem happened only during an update of the item, not while adding a new one - so it had to come when I was populating the element value.

$('#itemAcquiredTxt').val(new Date(item.DateAcquired).toLocaleDateString());

Doing a console.log(item.DateAcquired) returned a string "2015-12-15T00:00:00", the .toLocaleDateString() would convert it to "2015-12-15" and parsed into a Date object.

Editing that element's value would always result in a NaN/InvalidDate when trying to convert it's string into a date.

My solution was...

$('#itemAcquiredTxt').val(item.DateAcquired.split('T')[0]);

Not use Date at all. Now it works.

like image 77
Cuauhtemoc Avatar answered Sep 29 '22 19:09

Cuauhtemoc