Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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?

share|improve this question
    
I've answered your question below and I suggest you get a good MVC book (from Apress) and read about the request life-cycle. –  Josh Pearce Nov 14 '09 at 21:36

2 Answers 2

up vote 5 down vote accepted

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

share|improve this answer
    
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? –  Matt Powell Nov 16 '09 at 1:22
    
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. –  Matt Powell Nov 16 '09 at 1:36
    
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 Nov 16 '09 at 2:32

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>
share|improve this answer
    
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. –  Matt Powell Nov 14 '09 at 21:51
    
I have edited my answer to further explain. –  Josh Pearce Nov 14 '09 at 22:25
    
If you end up needing to get the id from the page address on the client, then check out the query plugin: plugins.jquery.com/project/query-object –  Josh Pearce Nov 14 '09 at 22:27
    
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! –  Matt Powell Nov 16 '09 at 1:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.