Search code examples
jqueryasp.net-mvcevopdf

Accessing ViewData in jQuery not working


I am trying to pass an IList back to my View where it can be accessible in a jQuery .each(), but I'm not having any success.

Example class:

public class MyClass
{
    private string _Name = "";
    public int Id = null;

    public MyClass ( string Name, int Id = null )
    {
       ... Do something ...
    }

    public string Name 
    { 
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
        }
    }
}

In Controller:

IList<MyClass> myClass = null;
myClass = GetNames();

ViewDataDictionary viewData = new ViewDataDictionary(null);
viewData.Add("myNames", Json(myClass));

// The string writer where to render the HTML code of the view
StringWriter stringWriter = new StringWriter();

// Render the Index view in a HTML string
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext,
    "GeneratePDF", null);

ViewContext viewContext = new ViewContext(
    ControllerContext,
    viewResult.View,
    viewData,
    new TempDataDictionary(),
    stringWriter
    );
viewResult.View.Render(viewContext, stringWriter);

... Omitted for brevity ...

In the View I would like to use jQuery to iterate through ViewData["myNames"]:

<script type="text/javascript">

    _myNames = '@ViewData["myNames"]';

    $.each(_myNames, function (i, item) {
        ...
    });

</script>

The above doesn't work and unfortunately I'm not sure how to debug it because the view is being called by EvoPDF PDF Generator.

I've also tried this in my View:

<input type="hidden" id="myNames" value="@ViewData["myNames"]" />

<script type="text/javascript">

    _myNames = $('#myNames').val();

    $.each(_myNames, function (i, item) {

    });

</script>

Tracing through the controller code (where EvoPDF renders the page) I can see that the hidden field is containing the Type Name in the value attribute - not the data.

I've used ViewData many times without problem, but this is a bit different usage than I'm familiar with. Can anyone tell me how to pass an IList/List/IENumerable using ViewData so that I can iterate through it with jQuery .each()?

EDIT

As an alternative, I could make a jQuery call from within my razor, but I'm not sure how to pass the variable to jQuery:

@foreach (var myName in (List<MyClass>)ViewData["myNames"])
{
    <tr>
    <td class="text-center">
        <script type="text/javascript">
            FormatName('@myName.Name', 1);
        </script>
    </td>
    </tr>
}

But myName.Name doesn't seem to being passed to the FormatName() function. I know for a fact that myName.Name contains a valid value because it renders fine without the jQuery. How do I pass that var to my jQuery function?


Solution

  • You first need to convert TempData property to a javascript array of objects. Oualid KTATA was on the right track with first suggestion, but that only returns a string. In you document ready function:

    var _myNames = JSON.parse('@Html.Raw(Json.Encode(ViewData["myNames"]))');
    

    which will return something like

    [{ID:1, Name:"FirstName"}, {ID:2, Name:"SecondName"}, ...]
    

    You can then access it with

    $.each(_myNames, function(index, item) {
      var id = item.ID;
      var name = item.Name;
    });