views:

571

answers:

2

Hi,

I'm trying to use JQuery's $.getJSON to access Model data from the Controller, and build a JSON object in the javascript to use as the user adds and removes items from a list. All JS is done in an external file. The hit to the server for the Model data is done only once after the page first loads so I can get the full list of options for the user to choose from. After that, the user can modify the list as much as he wants (and the JSON object is updated accordingly), and then save it off (gets written back to the DB).

But here's my problem: When using $.getJSON, the method I need to call in the Controller needs an ID so that it can look up what particular resource I'm talking about and get back the list of options that pertains to that particular resource. But from an external JS file, I don't know how to get that ID to pass to the Controller. It's built into the link that opens the page in the first place, and is sitting in the URL, but once the page loads I don't know how to get this ID in order to pass it to the Controller. I've pasted some of my code below, because I know this is confusing:

Details method in Controller that initially loads a page (takes a resourceID to know what to load):

public ActionResult Details(string resId)
{
    //call base method
    base.Details(resId, resourceType);
    Evaluation eval = (Evaluation)this.Model;
    ViewData.Model = eval;
    return View("Index");
}

In my external JS file, I'm doing this:

$.getJSON("/Evaluation/PopulateJournalOptions/" + id, populateJSON);

And in the Controller, I wrote another method called PopulateJournalOptions that gets called to build the JSON object:

public JsonResult PopulateJournalOptions(string resId)
{
   JournalOptionsResult jsonResult = new JournalOptionsResult();

   base.Details(resId, resourceType);
   Evaluation eval = (Evaluation)this.Model;

   jsonResult.Activities = eval.Journal.Activities;
   jsonResult.Issues = eval.Journal.Issues;
   jsonResult.ScheduledActions = eval.Journal.ScheduledActions;

   return Json(jsonResult);
}

Again, my problem is that, once the page loads, I don't have access to the ID I need to pass to PopulateJournalOptions. I've tried just not passing anything to PopulateJournalOptions, and creating a new object there and setting it equal to (Evaluation)this.Model, but this.Model appears to be null, probably because it's a new instance of the Controller once it's called from the JS. So I'm kind of stuck here. Any ideas?

+1  A: 

Put this in the controller:

ViewData["resouceID"] = resouceID;

Put this in the View that loads initially:

<script>
$(document).ready(function() {
    $.getJSON("<%=Url.Action("YourActionName", "YourControllerName", new {id = ViewData["resouceID"]}) %>", populateJSON);
});
</script>
Josh Pearce
Hi Josh, thanks for the quick reply. Can you briefly explain what this is doing? It looks like I might still have to supply the ID as "yourID". I've tested my code with a hardcoded id provided to $.getJSON and everything works, so my Controller calls, callbacks, routing, etc work fine, but I just don't know how to get the ID to pass to it. I may be misinterpreting your answer, but it looks like I still need to supply the ID. Also, will this work from an external JS file? Thanks again.
Mega Matt
I have edited my answer to further explain.
Josh Pearce
If you end up needing to get the id from the page address on the client, then check out the query plugin: http://plugins.jquery.com/project/query-object
Josh Pearce
Went ahead and used the answer given by tvanfosson below, but am using your Url.Action method in my external JS file. ID is being supplemented using the $(#id).html() option given below. Thanks for the answers!
Mega Matt
+2  A: 

Have you thought about putting the id into a hidden field on the page and then having your javascript read the id from the field?

$.getJSON("/Evaluation/PopulateJournalOptions/" + $('#Id').attr('value'), populateJSON);

Then, in your view,

<%= Html.Hidden("Id") %>

With your model having the required Id as a property

tvanfosson
I had not thought of that, and it's certainly an interesting approach. As easy as it is, I feel like it's sort of cheating. Does it seem that way to anyone else?
Mega Matt
The more I thought about this method, the more clean it started to sound, so I went ahead and implemented it. But instead of .attr('value'), I needed to use .html(). Otherwise, works great. Thanks for the response!As a side note, I really dislike how I'm hitting the server twice in order to build this JSON object (once to load page and another to call Controller action to return data for JSON). It would be awesome if I could get that JSON into an external javascript variable on page load, rather than having to go back to hit the server a second time.
Mega Matt
There's no reason you couldn't put the value into your model and then write it out into a javascript variable in the view. Using an AJAX callback will speed your initial page load, but if you can afford the time you could put it into the view directly.
tvanfosson