Second ajax call confuses url with object

Second ajax call confuses url with object

matt_gmatt_g Posts: 8Questions: 1Answers: 0
edited March 2018 in Free community support

I've got a search box on my page that updates data in a datatable. Here is the code:

var baseURL = "/api/Reservations?CustomerId=";

$("#btnSearch").on("click",
            function () {
                var custEmail = $("#txtEmail").val();
                var customer = $.ajax(
                    {
                        url: "/api/Customers?email=" + custEmail,
                        data: "",
                        success: function (customer) {
                            var ajaxurl = baseURL + customer.id;
                            var ajaxobj = {
                                url: ajaxurl,
                                dataSrc: ""
                            };
                            dt.ajax.url(ajaxobj).load();
                            dt.clear().draw();
                        },
                        error: function () {
                            bootbox.alert("Doesn't look like you've made any bookings.");
                        }
                    });
            });

When I load the page, enter an email address in my searchbox and click the button, everything works perfectly. It searches the customer, retrieves the bookings and populates the table.

The request it makes to the reservations API looks like this:

http://localhost:55601/api/Reservations?CustomerId=6&_=1522178504857

(I'm not sure how or why &_=1522178504857 gets appended, but it doesn't seem to be affecting it so I'll come back to that...)

However, if I click the search button a second time, the customer is still retrieved correctly, however request to the reservations API looks like this:

http://localhost:55601/Reservations/[object%20Object]?_=1522178504858

(URLs in both cases I've retrieved from developer tools).

Just to show what happens:

Why? What have I done wrong?

EDIT: updated code formatting using Markdown

Answers

  • kthorngrenkthorngren Posts: 21,150Questions: 26Answers: 4,918

    You have this in the AJAX call:
    var ajaxurl = baseURL + customer.id;

    Not sure where that is coming from but you also have this:
    var customer = $.ajax(

    I suspect the second time customer is the ajax call or something you are not expecting it to be.

    _=1522178504857
    That has do do with disabling cache for the ajax request (look for the cache option):
    http://api.jquery.com/jquery.ajax/

    Kevin

  • matt_gmatt_g Posts: 8Questions: 1Answers: 0

    Thanks Kevin, the purpose of the search is to look up a customer ID by the supplied email address (which works every time), then use that ID to return all reservations for that customer ID (which works the first time, then fails all subseuqent times).

    Given that the customer is returned correctly every time, I'm not sure how the issue happens on all occassions after the first run.

  • kthorngrenkthorngren Posts: 21,150Questions: 26Answers: 4,918

    I missed the customer parameter in this line:
    success: function (customer) {

    I would start by adding console.log(customer); as the first line of your success function. What does it show?

    Kevin

  • matt_gmatt_g Posts: 8Questions: 1Answers: 0

    added consol.log(customer) as you suggest, it shows the same thing every time:

    {Name: "John", PhoneNumber: "0123456789", EmailAddress: "john@smith.com", id: 6}
    EmailAddress
    :
    "john@smith.com"
    Name
    :
    "Matt"
    PhoneNumber
    :
    "0123456789"
    id
    :
    6
    __proto__
    :
    constructor
    :
    ƒ Object()
    hasOwnProperty
    :
    ƒ hasOwnProperty()
    isPrototypeOf
    :
    ƒ isPrototypeOf()
    propertyIsEnumerable
    :
    ƒ propertyIsEnumerable()
    toLocaleString
    :
    ƒ toLocaleString()
    toString
    :
    ƒ toString()
    valueOf
    :
    ƒ valueOf()
    __defineGetter__
    :
    ƒ __defineGetter__()
    __defineSetter__
    :
    ƒ __defineSetter__()
    __lookupGetter__
    :
    ƒ __lookupGetter__()
    __lookupSetter__
    :
    ƒ __lookupSetter__()
    get __proto__
    :
    ƒ __proto__()
    set __proto__
    :
    ƒ __proto__()
    
  • matt_gmatt_g Posts: 8Questions: 1Answers: 0
    edited March 2018

    I've added some more logging, and this is what I've found:

    On the first click, the url is an object which has a dataSrc property and a url property. On the second click it's a string.

    I'm just not sure why it would change from one click to the next, given that the code is the same?

  • kthorngrenkthorngren Posts: 21,150Questions: 26Answers: 4,918

    That is strange, not sure without trying it out. However the ajax.url() expects a string parameter. Maybe try removing the object and just using a string.

    Kevin

  • matt_gmatt_g Posts: 8Questions: 1Answers: 0
    edited March 2018

    Thanks Kevin, I did initially have it as a string but got an undefined error. So changed it to an object and then it worked, but only the rist time it runs after loading the page.

  • matt_gmatt_g Posts: 8Questions: 1Answers: 0
    edited March 2018

    Just to further confuse things...I was playing with the code, changing between passing dt.ajax.url() the object and the string. Now it logs without the child object every time in the console (including the first itme it runs, which still works):

    {url: "/api/Reservations?CustomerId=6", dataSrc: ""}
    data
    :
    undefined
    dataSrc
    :
    ""
    url
    :
    "/api/Reservations?CustomerId=6"
    

    This makes sense, it's what I'd expect to see. Happy to write off the appearance of the child object as a non-repropducable anomoly as it doesn't seem to have affected the outcome.

  • matt_gmatt_g Posts: 8Questions: 1Answers: 0
    edited March 2018

    Just in case it helps, here is where I initialise my table:

    var dt = $("#reservations").DataTable(
                    {
                        columns: [
                            {
                                data: "ReservationStart",
                                render: function (data) {
                                    return $.format.date(data, "d MMM, yyyy h:mm a");
                                }
    
                            },
                            {
                                data: "Covers"
                            },
                            {
                                data: "id",
                                render: function (data) {
                                    return "<button class='btn btn-primary js-edit' data-reservation-id=" + data + ">Edit</button> &nbsp; <button class='btn btn-secondary js-delete' data-reservation-id=" + data + ">Delete</button>";
                                }
                            }
                        ]
                    }
                );
    
    
  • matt_gmatt_g Posts: 8Questions: 1Answers: 0

    I've managed to figure out what the problem is. Normally, when you initialise your table, you specify an ajax object:

    $("#mytable").DataTables({
        ajax:
        {
            url: [api url],
            dataSrc: [data source or blank]
        },
        columns:
        [
            etc...
        ]
    });
    

    In my case, because I don't have the data until the user executes the search, I haven't specified this. Therefore, when I first run the ajax call for the datatable (not for the customer search), I have to pass it an object. Passing it the URL only results in an undefined error.

    However, on subsequent runs, as the ajax object is already defined at this point, passing an object as the URL parameter has the expected effect - the URL is an object hence the [object%20Object] we are seeing.

    I had tried using the destroy() function previously to no effect. So, my workaround is simply to use an iteration counter. On the first run I pass it the object, on subsequent runs I pass it the URL.

    I'm not sure if there's a better way of doing this.

This discussion has been closed.