0

I'm working on a website that, among other things, have items with prices that are pulled from "outside" on controller level. Controller then returns the Json object to the Ajax complete function and one of the properties is supposed to replace the content of a certain html element.

This is the Ajax call:

$('.price').each(function (i, e) {
    var id = $(e).attr('name');
    var exterior = $(e).attr('title');

    $.ajax({
        type: "GET",
        url: "/Skin/GetPrice",
        data: { Id: id, Exterior : exterior },
        cache: false,
        dataType: "json",

    }).complete(function (data) {
        if(data.responseJSON.success)
        {
            var val = data.responseJSON.lowest_price;
            $(e).html(""); //this works and DOES clear the content of the element
            $(e).html(val); // this does NOT work
            $(e).html(data.lowest_price); // this also doesn't work - returns "undefined"
            $(e).html(data.responseJSON.lowest_price); // this also doesn't work
            $(e).attr('title', 'Steam Market price for ' + exterior);
            $(e).removeClass('loading-cube');
            $(e).addClass('padding10');
        }
    });
});

I am 100% sure that I'm getting the object properly, besides data.responseJSON.success checks properly.

enter image description here

I have no idea why this is happened, but I'm sure there's an easy fix for this that I'm not aware of..

here's the return command in the controller:

return Json(new { success = true, lowest_price = data["lowest_price"].ToString() });

HTML:

<div class="cell">
    <a href="#" class="price block full-size loading-cube" name="@Model.Skin.Id" title="@e.Name">Fetching...</a>
</div>
DethoRhyne
  • 930
  • 1
  • 9
  • 29

2 Answers2

0

First of all complete is a property of your settings object of your ajax call, not an event on the xhr object.

This should work fine.

$.ajax({
         type: "GET",
         url: "@Url.Action("GetPrice", "YourControllerNameHere")",
         data: { Id: id, Exterior: exterior },   
         complete: function(data) {
                   if (data.responseJSON.success) {
                      var val = data.responseJSON.lowest_price;
                       $(e).html(val);
                    }
       });

Also since it is a GET request, Make sure you explcitily allow returning json from an GET action method in your controller by specifying JsonRequestBehavior.AllowGet as the second parameter of the Json method.

public ActionResult GetPrice(string id,string Exterior="")
{
   return Json(new { success = true, lowest_price = 123.ToString() },
                                                             JsonRequestBehavior.AllowGet);
}

Your server code returns a json structure with a success property and a lowest_price property. So simply use data.success

The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise including the done method. So you may also consider using the done callback. The below code should also work.

$.ajax({
    type: "GET",
    url: "@Url.Action("GetPrice", "YourControllerNameHere")",
    data: { Id: id, Exterior: exterior }

}).done(function (data) {       
    if (data.success) {
        var val = data.lowest_price;
        $(e).html(val);
    }
});
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • How does your HTML markup looks like ? Can you include that in the question? – Shyju Sep 13 '16 at 15:49
  • Yes, I'll edit it now. Also, data.success appears to be a function. no property can be accessed with that. http://prntscr.com/chkgkv < watch window – DethoRhyne Sep 13 '16 at 15:50
  • js script is not a part of the view, it's in a separate file. controller part is fine for sure, maybe only the return should be differently structured... – DethoRhyne Sep 13 '16 at 16:08
  • I tested the above code and both approaches works fine. If your js file is not in the view, you can't directly use the `Url.Action` method. See the solutions provided in [How do I make JS know about the application root?](http://stackoverflow.com/questions/34360537/how-do-i-make-js-know-about-the-application-root/34361168#34361168) – Shyju Sep 13 '16 at 16:13
  • Whatever I did I did get the right object back and it wouldn't save. but now I've managed to get it working.. posting information below as an answer. – DethoRhyne Sep 13 '16 at 18:13
  • Your original question had nothing to do with save. It was about getting data with Ajax and updating the ui. – Shyju Sep 13 '16 at 18:15
  • Yes it was. My question was why ajax model, even though seemingly ok, won't update the ui even though I used .html(***). – DethoRhyne Sep 13 '16 at 18:56
0

I've fixed the problem and here are the steps:

I have changed the return type of the Action from IActionResult to ActionResult:

[HttpGet]
public async Task<ActionResult> GetPrice(int Id = 0, string Exterior = null)
{

}

I have created a model for the search query:

public class PriceViewModel
{
    public bool QuerySuccessful { get; set; }
    public bool ListingExists { get; set; }
    public string Price { get; set; }
}

after filling out the model and returning it back to the query I use the .responseJSON property of the returned data to access the properties:

   .complete(function (data) {
            var price = data.responseJSON.price;
            if (data.responseJSON.querySuccessful)
            {
                if (data.responseJSON.listingExists)
                {
                    $(e).html(price);
    ....
DethoRhyne
  • 930
  • 1
  • 9
  • 29