0

I have a generic MVC aspnetcore setup, that pulls data from a local DB that is full with all USA zip codes, the state and city they are associated with. I am trying to pull back suggestion after say 3 digits are put in for what state they should be inferring and then to fill in the missing city after 5 digits are placed in the textbox. The issue that is baffling me is that within the javascript function data has the returned information. But that information is lost once the scope has left the function and also trying to set the value of another textbox to any of that information fails.

My view

@section Scripts{
     <script src="Scripts/jquery-1.5.min.js" type="text/javascript"></script>
     <script src="~/js/data.js" type="text/javascript"></script>
}
<div class="form-group">
    <label asp-for="Zip" class="col-xs-2 control-label"></label>
    <div class="col-xs-6">
        <input id="Zip" asp-for="Zip" class="form-control" onkeyup="loadData()"/>
        <span asp-validation-for="Zip" class="text-danger" />
    </div>
</div>

My javascript file

function loadData() {
     var str = $("#Zip").val();
     if (str.length == 3){
        $.get("/Localities/OnChange", { id: str }, function (data) {
            $("#Code").val(data.code);
        });
    }
    if (str.length == 5) {
        $.get("/Localities/OnChange", { id: str }, function (data) {
            $("#Boroughs").val(data.boroughs);
            $("#City").val(data.city);
            $("#Code").val(data.code);
            $("#Country").val(data.country);
            $("#County").val(data.county);
            var temp = data.city;
        });
    }
}

My controller

 [HttpGet]
    public Localities OnChange(string id)
    {
        Localities temp = _context.Localities.FirstOrDefault(x => x.Zip.StartsWith(id));
        var temp2 = JsonConvert.SerializeObject(temp);
        return temp;
    }

This shows I can get data back from DB

Edward
  • 864
  • 1
  • 7
  • 29
  • ..because `data` is an argument passed to your `$.get` callback function, so it's scope is within that function. If you want it to be scoped somewhere else, you have to push it somewhere else, like a global variable or some other namespaced variable designated to store/reference things of this nature. – CrayonViolent Sep 16 '18 at 00:31
  • Super basic example to get point across: `window.data = data;` this will push it to a globally (window) scoped variable of the same name. This is generally bad practice, though. Better to push it to some data handler layer. – CrayonViolent Sep 16 '18 at 00:34
  • I believe I tried passing it to a variable within the loadData function and it wouldn't do that, just like its not setting any of the textbox values; so even though I haven't tried created a more global value in the view not sure how that would give a different outcome. – Edward Sep 16 '18 at 00:39
  • Possible duplicate of [(still) more confusion over javascript closures, ajax, and return values](https://stackoverflow.com/questions/11248543/still-more-confusion-over-javascript-closures-ajax-and-return-values) – Martin Zeitler Sep 16 '18 at 00:40
  • I understand proper wrappers can easily blow up code. As to understanding ajax (not fully) but my main issue is probably why after it leaves the .get having sent the response when the data finally does get returned how do I go about finally populating the information like I am trying to do. – Edward Sep 16 '18 at 00:48

1 Answers1

0

There is few potential issues here:

1) In this code here:

function loadData() {
     var str = $("#Zip").val();
     if (str.length == 3){
        $.get("/Localities/OnChange", { id: str }, function (data) {
            $("#Code").val(data.code);
        });
    }
    if (str.length == 5) {
        $.get("/Localities/OnChange", { id: str }, function (data) {
            $("#Boroughs").val(data.boroughs);
            $("#City").val(data.city);
            $("#Code").val(data.code);
            $("#Country").val(data.country);
            $("#County").val(data.county);
            var temp = data.city;
        });
    }
}

var temp in second GET will only be available with in the function that is in now.

Second which is most likely why your code is not showing data is because it is most likely

data.data.city and data.data.code and so on

if you do console.log(data); I am pretty sure it is nested with in another data wrapper.

Let me know I would change function variable to function(response) so you are note confused by the level you are at.

This should work or at least give you a better idea of what is broken:

var temp; // Global

function loadData() {
         var str = $("#Zip").val();
         if (str.length == 3){
            $.get("/Localities/OnChange", { id: str }, function (response) {
                $("#Code").val(response.data.code);
            });
        }
        if (str.length == 5) {
            $.get("/Localities/OnChange", { id: str }, function (response) {
                $("#Boroughs").val(response.data.boroughs);
                $("#City").val(response.data.city);
                $("#Code").val(response.data.code);
                $("#Country").val(response.data.country);
                $("#County").val(response.data.county);
                temp = response.data.city;
            });
        }
    }

Also check your console for any other errors, that may be preventing the code from executing.

CHECK THIS:

Right click element and grab ID

<input type="text" id="#city">

this ID might be different than you are expecting it to be after render

I am Cavic
  • 1,115
  • 1
  • 10
  • 22
  • 1
    `var temp;` probably should be defined outside the callback scope - and then be populated with `temp = data.city`, within the callback scope... or maybe even called `lastResponse`. also passing response data into functions helps with callback hell. – Martin Zeitler Sep 16 '18 at 00:43
  • @MartinZeitler yeah you are 100% correct, I am not sure what he is using it for but I am sure that it is not available to him. So yes he will have to declare it on global level and populate it that way. – I am Cavic Sep 16 '18 at 00:45
  • Well i put the temp variable there with a breaker, so that I can actually see the values that are being returned. When I have tried a break outside the .get I do see other wrapper that appears to have hundreds of nothing burgers in it (aka nothgin that means any real data to me) – Edward Sep 16 '18 at 00:46
  • @Edward i understand, did you try what I wrote above? I will update my answer and you can copy past the code and see how it works. – I am Cavic Sep 16 '18 at 00:53
  • wwell I took out the temp line, and added the extra `data.` that didn't help. And I thank the fact Intellisense doesn't appear to help in those instances – Edward Sep 16 '18 at 00:58
  • let me know what you are getting when you do this in your get functions `console.log(response.data)` make sure to update your `function(data)` to `function(response)` – I am Cavic Sep 16 '18 at 00:59
  • That is an error provided by your .NET Core so you are most likely not reaching your back end code. You can put a break point on the first line of your function and see if you are reaching it. @Edward – I am Cavic Sep 16 '18 at 01:19
  • @Edward correct, your ajax call hits an error so your response doesn't have results it just shows you an error. If you click in your inspection on Network tab you will be able to see more details on the error but I am 100% that you are 1) not reaching your back end function in c# or 2) something breaks in your function which throws the error. – I am Cavic Sep 16 '18 at 01:33
  • I added a pic to the question to show I get data returned from the DB with my original code – Edward Sep 16 '18 at 01:45
  • @Edward I see, so you are reaching the code, can you show me your HTML / ASP code. Are you using master page? I feel that your elements are not correct, when page renders check what your element ID is at that time.. Sometimes depending on how you have built your front end your ELEMENTS get prifixed or sufixed by main wrapper so your `#city` is actually `#city_something` or `#sometihng_city` and that is why your data is not populating.. – I am Cavic Sep 16 '18 at 01:52
  • You kinda lost me there. I just have a basic MVC aspnetcore template with Identity framework added. Are you wanting the actual HTML on the browser return? There isn't much left to my code other that the data Models – Edward Sep 16 '18 at 02:00
  • Do this .. When you page renders, right click the INPUT field CITY for example and do `Inspect` than take a look in the source and see what the ID is of that INPUT.. use those IDs in your JavaScript to populate values...@Edward – I am Cavic Sep 16 '18 at 02:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/180130/discussion-between-i-am-cavic-and-edward). – I am Cavic Sep 16 '18 at 02:06