1

I am making a text-box with drop down for auto-completing suggestion using jquery and ajax but the error I have found through debugging is that when the debug point comes to the given code it successfully moves to return statement and when comes second time on the same statement it gives an exception that "Keyword is null" (Keyword is the alphabet entered by the user in the textbox)

var result = (from a in objGameList where
a.GameName.ToLower().StartsWith(keyword.ToLower()) 
select new { a.GameName });

Here is the code:

Index.cs

<script type="text/javascript">
    $(document).ready(function () {
        $("#GameName").autocomplete({
            source: function (request, response) {
                $.ajax({    
                    url: "/Home/Index",    
                    type: "POST",    
                    dataType: "json",    
                    data: { keyword: request.term },   
                    success: function (data) {   
                        response($.map(data, function (item) {    
                            return { label: item.GameName, value: item.GameName };    
                        }))    
                    },    
                    error: function () {    
                        alert('something went wrong !');    
                    }    
                })    
            },   
            messages: {   
                noResults: "", results: ""    
            }    
        });    
    })    
</script>
        
@using (Html.BeginForm())    
{    
    @Html.AntiForgeryToken()   
    <div class="form-horizontal">    
        <div class="form-group">    
            <div>       
                @Html.EditorFor(model => model.GameName, new { htmlAttributes = new { @class = "form-control" } })   
            </div>    
        </div>        
    </div>   
}
```

Controller.cs

[HttpPost]
    public JsonResult Index(string keyword)
    {
        //This can be replaced with database call.
    
        List<Games> objGameList = new List<Games>(){
            new Games {Id=1,GameName="Cricket" },
            new Games {Id=2,GameName="Football" },
            new Games {Id=3,GameName="Chesh" },
            new Games {Id=4,GameName="VallyBall" },
        };
    
        var result = (from a in objGameList
                        where a.GameName.ToLower().StartsWith(keyword.ToLower())
                        select new { a.GameName });
    
        return Json(result);
    }

Thanks in advance.

12
  • Couldn't reproduce it with provided code. when comes second time on the same statement - what do You exacly mean by that? It hits breakpoint inside the controller for the second time without calling AJAX? Or You type and delete a letter, forcing autocomplete to send the same request and the second one does not have any data with it? Which version of the jQuery and jQuery UI are You using? I've used jQuery 1.12.4 and UI 1.12.1 to reproduce with no results. Commented Feb 15, 2020 at 22:06
  • There is no Model definition in your View... the following is invalid: @Html.EditorFor(model => model.GameName Commented Feb 15, 2020 at 23:08
  • @HoomanBahreini The controller action shown does not correspond to the view code that is being displayed. The controller action is being called through AJAX and returns JSON. Commented Feb 16, 2020 at 0:35
  • @Eatos When i enter the text in textbox the debug point reaches the function in controller, it goes to return statment for the first time successfully when postback to the given statement it gives the mentioned error Commented Feb 16, 2020 at 12:11
  • Sorry, if I understand correctly: type "C", controler returns, type "r", controller returns, remove "r", controller throws error? Which version of the libraries? This is happening regardless of text You are typing (with match or not)? With versions I tried if immediately returned from "Cr" to "C" the API is called only 1, not 3 times (it detects that the value did not change from "C"). Maybe Your version works differently? Commented Feb 16, 2020 at 14:47

2 Answers 2

2

So I made an example from scratch to see if it wouldn't work and... it worked so please follow the example and try to figure out what is different in your aproach. I'll point out every change I made compared to the code fragments You have provided.

I'll start with the new empty project.

dotnet new mvc -o test

I copy and paste entire POST action of Yours into the HomeController.cs, fixing imports and generating a missing Games model, putting that file into .\Models\Games.cs:

namespace test.Models
{
    public class Games // changed the default visibility to public
    {
        public int Id { get; set; }
        public string GameName { get; set; }
    }
}

I replaced content of ./Views/Home/Index.cshtml with Your view (adding at the top of the file the line: @Model Games to let the view know about the model so the @Html.EditorFor() be able to generate the form control - without it i got an error: CS1963 An expression tree may not contain a dynamic operation):

So:

@model Games
<script type="text/javascript">
...

I have putted jQuery imports in .\Shared\_Layout.cshtml:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
...

and removed reference to any other js file:

...
    </footer>
</body>
</html>

Lastly I have edited the default action of HomeController:

public IActionResult Index()
{
  return View(new Games()); // added new Games object to be injected as a model for the view.
}

At that stage I do not encounter anything what You have described. Although I got an error: Uncaught TypeError: this.options.messages.results is not a function but this is something completly different and can be solved by replacing

    messages: {
        noResults: "", results: ""
    }
});

with this:

    messages: {
        noResults: "", results : function(count) {
        return "";
      }
    }
});

The solution results in no errors and working mechanism.

Please play around with it, it simply ahould work. All I can come up with is the different library version.

Sign up to request clarification or add additional context in comments.

1 Comment

Thankyou so much for your kindness @Eatos. It worked.
0
dataType: "json",
data: { keyword: request.term },

You are sending data as JSON like this. That means that there is a single object being sent to the server with a keyword property.

When sending JSON objects to the server, you should always create a custom complex object in order for ASP.NET Core to deserialize it properly:

public class AutoCompleteViewModel
{
    public string Keyword { get; set; }
}
[HttpPost]
public JsonResult Index(AutoCompleteViewModel model)
{
    // work with model.Keyword instead
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.