Problem with javascript method coming from controller by Session

Asked

Viewed 674 times

0

That is the mistake:

Uncaught Typeerror: Cannot read Property '0' of Undefined

Well, here’s the thing:

I do a search on a WS. On the return of this search, I mount an html and play in my view (cshtml). Well, this works.

Then I made some filters to search inside my Session, that information. Let’s say in my Session, I have 29 Hotels. There, by the name filter of the hotel (a Textbox) I select a Hotel (There is an auto complete, which is working). I select the hotel. No OnBlur of textbox, i call a Jquery function to load the chosen hotel into the textbox.

It loads and at that moment, I take the same html that works on the first load, gives this error. I no longer know what to do. The code of the functions that carry html are large, so I didn’t post them, but I can do it if you want.

My searchResult giving error in the search

[HttpPost]
public JsonResult FiltroGeral(string[] refeicoes, string hotel, string[] categoria)
{
    OfferV2[] pesquisaHotel = ((OfferV2[])SessaoUtil.Recuperar("PegaHotelPacote"));

    List<object> searchResult = new List<object>();

    if (refeicoes != null)
    {
        pesquisaHotel = pesquisaHotel.Where(x => refeicoes.Contains(x.CategoryId)).ToArray();
    }

    if (hotel != "")
    {
        pesquisaHotel = pesquisaHotel.Where(x => hotel.Contains(x.ProductName)).ToArray();
    }

    if (categoria != null)
    {
         pesquisaHotel = pesquisaHotel.Where(x => categoria.Contains(x.CategoryId)).ToArray();
    }
    searchResult.Add(pesquisaHotel);
    return Json(new { searchResult }, JsonRequestBehavior.AllowGet);

}

This is my jquery

function FiltroGeral() {

        var Refeicoes = [];
        var Hotel = [];
        var Categoria = [];
        var str;
        var filtro;
        var cont = 1;
        var count = 1;
        var camas = [];
        var strHotel;
        var strCategoria;
        var valor = 0;
        var menorValor = 0;
        var parcelas;
        var qQuartos;

        dados = []

        for (var i = 0; i < filtroPesquisa.chkcategoria.length; i++) {

            if (filtroPesquisa.chkcategoria[i].checked) {

                Categoria.push(filtroPesquisa.chkcategoria[i].value);
            }
        }

        for (var i = 0; i < filtroPesquisa.chkrefeicao.length; i++) {

            if (filtroPesquisa.chkrefeicao[i].checked) {

                Refeicoes.push(filtroPesquisa.chkrefeicao[i].value);
            }
        }

        $.ajax({

            url: '/Hotel/FiltroGeral',
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            type: "POST",
            data: JSON.stringify({ refeicoes: Refeicoes, hotel: $("#txtNomeHotel").val(), categoria: Categoria, Min: $("#ValorMin").val().replace(".", "").replace(",00", ""), Max: $("#ValorMax").val().replace(".", "").replace(",00", "") }),
            success: function (data) {

                $(data.searchResult).each(function () {

                    alert(ProductName);

                    //menorValor = this.SubOfferGroups[0].AnswerOffersList[0].SalePrice.Value;

                    //$(this.SubOfferGroups).each(function () {

                    //    $(this.AnswerOffersList).each(function () {

                    //        menorValor = Math.min(this.SalePrice.DefaultValue, this.SalePrice.DefaultValue);
                    //    });
                    //});

                    if ($('#ValorHotel').val() != 0) {
                        menorValor = menorValor.toFixed(2) / $('#ValorHotel').val();
                        parcelas = $('#ValorHotel').val() + ' x'
                    }

                    str += '<div class="conteudo"> ';//Div inicial geral, fechar após tudo

                    str += '<div class="grid_11 margin-left-clear">';
                    str += '<div>';
                    str += '<h1>';
                    str += this.ProductName;
                    str += '        </h1>';
                    str += '<div class="valor">' + parcelas + ' ' + menorValor.toFixed(2) + '</div>'; // Inserir o valor com o parcelamento aqui
                    str += '<p>' + this.ShortDescription + '</p>';
                    str += '</div>';
                    str += '</div>';

                    str += '<div class="grid_8 margin-right-clear">';
                    str += '<div class="img-detalhes-hotel">';

                    str += '<img src="' + this.ImageList[0].URL + '" width="290" height="178" />';

                    str += '</div>';
                    str += '</div>';

                    str += '<div class="grid_19 row margin-bottom-10">';
                    str += '<div class="tab-detalhes-produto">';
                    str += '<a href="#fotos-0' + cont + '">Fotos</a>';
                    str += '</div>';

                    str += '<div class="tab-detalhes-produto">';
                    str += '<a href="#mapa-0' + cont + '">Mapa</a>';
                    str += '</div>';

                    str += '<div class="tab-detalhes-produto">';
                    str += '<a href="#servicos-0' + cont + '">Servicos</a>';
                    str += '</div>';

                    str += '<div class="tab-detalhes-produto">';
                    str += '<a href="#selecionar-quartos-0' + cont + '">Selecionar apartamento</a>';
                    str += '</div>';
                    str += '</div>';

                    str += '<div id="fotos-0' + cont + '" class="grid_19 fotos">';
                    str += '<div class="css3slider">';

                    if (this.ImageList.length > 0) {
                        $(this.ImageList).each(function () {

                            str += '       <input type="radio" name="slide_switch" id="' + cont + 'id' + count + '" checked="checked" />';
                            str += '       <label for="' + cont + 'id' + count + '">';
                            str += '            <img src="' + this.URL + '" />';
                            str += '        </label>';
                            str += '        <img src="' + this.URL + '" width="390" height="262" />';

                            count++;
                        });
                    }

                    str += '</div>';
                    str += '</div>';

                    str += '<div id="mapa-0' + cont + '" class="grid_19 mapa-localizacao-hotel">';
                    str += '<div class="map-canvas" data-opt=' + ' {"txtLatitude":' + this.Latitude + ',"txtLongitude":' + this.Longitude + '}' + ' style="display: block;width: 750px;height: 300px;"></div>';
                    str += '</div>';


                    str += '<div id="servicos-0' + cont + '" class="grid_19 servicos-hotel">';
                    str += '<p>' + this.Description + '</p>';
                    str += '</div>';

                    str += '<div id="selecionar-quartos-0' + cont + '" class="grid_19 selecionar-quartos">';
                    str += '<div class="grid_18 margin-left-15">';
                    str += '<h1>Selecione seus quartos de acordo com sua preferência</h1>';

                    $(this.SubOfferGroups).each(function () {

                        $(this.AnswerOffersList).each(function () {

                            valor = this.SalePrice.Value;

                            if (valor == "") {
                                valor = 0;
                            }

                            if ($('#ValorHotel').val() != 0) {

                                valor = valor.toFixed(2) / $('#ValorHotel').val();
                            }

                            str += '<div class="display-table border-bottom-cinza">';

                            str += '<div class="display-table">';
                            str += '<div class="grid_8">';
                            str += '<div class="valor">';
                            str += '<input type="checkbox" value="1" />';
                            str += this.ProductName + ' ' + parcelas + ' ' + valor.toFixed(2);
                            str += '</div>';
                            str += '</div>';

                            str += '<div class="grid_5">';
                            str += '<select class="select-group">';
                            str += '<option>Qtd. quartos</option>';

                            for (var i = 1; i < $("#Quartos").val() + 1; i++) {

                                if (i == 1)
                                    str += '<option>' + i + ' quarto</option>';
                                else
                                    str += '<option>' + i + ' quartos</option>';
                                if (i == $("#Quartos").val())
                                    break;
                            }
                            str += '</select>';
                            str += '</div>';


                            str += '<div class="grid_4 selecionar-quartos-adicionais">';
                            str += '<a href="#dados-adicionais-quarto-0' + cont + '">+ informações</a>';
                            str += '</div>';
                            str += '</div>';

                            str += '<div id="dados-adicionais-quarto-0' + cont + '" class="dados-adicionais-quarto">';
                            str += '<div class="grid_11">';
                            str += '<table class="table table-bordered table-hover">';
                            str += '<thead>';
                            str += '<tr>';
                            str += '<td>Pessoas</td>';
                            str += '<td>Data</td>';
                            str += '<td>Preço</td>';
                            str += '</tr>';
                            str += '</thead>';

                            var adt = $('#txtAdulto').val();
                            var cri = $('#txtCrianca').val();

                            str += '<tbody>';
                            str += '<tr>';
                            str += '<td>' + (adt > 0 ? adt + ' Adulto(s)' : "") + ' ' + (cri > 0 ? cri + ' Criança(s)' : "") + '</td>';
                            str += '<td>' + '' + '</td>';
                            str += '<td>' + this.SalePrice.Value.toFixed(2) + '</td>';
                            str += '</tr>';
                            str += '</tbody>';

                            str += '</table>';
                            str += '</div>';
                            str += '<div class="grid_4">';

                            str += '<p>aqui será inserido o texto referente a serviços inclusos e politica de cancelamento</p>';
                            str += '</div>';
                            str += '</div>';
                            str += '</div>';

                        });
                    });
                    str += '</div>';
                    str += '</div>';

                    str += '</div>';

                    dados.push(str);

                    cont++;

                    str = "";

                    $("#Pagination").pagination(dados.length, {

                        items_per_page: 5,
                        num_display_entries: 1,
                        num_edge_entries: 1,
                        callback: pageselectCallback

                    });
                });

            },
            error: function (error) {
                alert("erro");
            }
        });
    }
  • Inform the line that gives error. Or just the trecha of the function that gives this error.

  • str += '<div class="grid_8 margin-right-clear">'; str += '<div class="img-details-hotel">'; str += '<img src="' + (this.ImageList.length != 0 ? this.Imagelist[0].URL : 0) + 'width="290" height="178" />'; str += '</div>'; str += '</div>'; The error of da no this.Imagelist, by the way everything that comes in my searchResult, says that and Undefined

  • this.Imagelist is undefined in this case. Check the context, maybe even the "this" reference is Undefined. What is the method that loads the context of this "this" ?

  • If it were the this, then the mistake would be Cannot read property 'ImageList' of undefined... unless he has something like this[0], there could be.

  • You do: this.Imagelist[0]

  • @pnet: Now yes, with all the information you can answer the question. Always post the code, or relevant snippets of the code to get help.

Show 1 more comment

1 answer

1

Not knowing exactly the code in which the error occurs(OP added error line), what I can do is try to explain in which situations this error occurs.

If a variable is defined, but has no value in it, that is, it is undefined then it won’t be possible:

  • read properties of this variable

  • call methods in that variable

  • use indexes in that variable

  • use associative keys in this variable

Example of the condition in which the error occurs

var array;
var valor = array[0];

Code review

Your code is in some trouble, which you may not have noticed.

In the C#:

  • the variable searchResult is a list of objects, and when you use the method Add, only one object is being added. This object being added is an array... this means that the element 0 of this list is an array of several objects, it is like a list within another list.

  • You call ToArray often, which makes the code less efficient. It would be best to operate directly on a Iqueryable or Ienumerable. As your data source already returns an array, then we can use Ienumerable, and then apply all filters successively by calling ToArray or ToList only once.

  • When returning JSON, there is no need to create an object only to contain a single variable... it could return the list directly: ``

  • The action is marked with the attribute HttpPost, which prevents being made a GET in this method. Then there is no reason to use the option JsonRequestBehavior.AllowGet.

  • The verification of the variable hotel against "" is not enough, because it could be null, or contain only blank spaces. So the best is to use string.IsNullOrWhiteSpace to make the check.

What C would look like#:

[HttpPost]
public JsonResult FiltroGeral(string[] refeicoes, string hotel, string[] categoria)
{
    var pesquisaHotel = ((IEnumerable<OfferV2>)SessaoUtil.Recuperar("PegaHotelPacote"));

    if (refeicoes != null)
    {
        pesquisaHotel = pesquisaHotel.Where(x => refeicoes.Contains(x.CategoryId));
    }

    if (!string.IsNullOrWhiteSpace(hotel))
    {
        pesquisaHotel = pesquisaHotel.Where(x => hotel.Contains(x.ProductName));
    }

    if (categoria != null)
    {
        pesquisaHotel = pesquisaHotel.Where(x => categoria.Contains(x.CategoryId));
    }

    return Json(pesquisaHotel.ToList());
}

Having the code this way, in javascript could do so:

  • instead of using $(data.searchResult).each( could apply directly to data:

    $(data).each(function () {
    
  • within that function, the this would be the object itself equivalent to OfferV2... the way it was before, that wasn’t true, by chance of the problem I pointed out about a list within another list.

In short, the error is inside the C#code, at the moment it adds a list inside the other:

searchResult.Add(pesquisaHotel);
  • Okay, Miguel, I get it. But look at my scenario. It all comes from a Septssion that’s loaded. If I break into my searchResult, there’s all the data there. So, it shouldn’t be Undefined. There’s something I’m not getting

  • What is this searchResult? How does it relate to the current context? You didn’t mention anything about this variable.

  • searchResult is the return of my controller. There are two methods. The first when I enter the page and after being on the page, comes the search and returns this searchResult with the search information. I can post, but in the comment section does not give the limit of characters. I’ll edit my post and send these guys, but like I said, it can get really big.

  • All this is loaded into a Session and then the search is done in Session

  • Could you please post the code of the call AJAX, which is made in javascript? I have a suspicion that the error is there.

  • I posted all my jquery

  • @pnet: I updated the answer with some points referring to the code posted.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.