0

I'm using vis.js to create a timeline, and am trying to understand where I'm going wrong when trying to pass JSON from my model to the view. The timeline accepts data in JSON format, for example:

var data =  [
{"content": "item 1", "start": "2016-08-20"},
{"content": "item 2", "start": "2016-08-21"},
{"content": "item 3", "start": "2016-08-21"}];

I have a model the looks like the following:

public class MyModel
{
    public ModelData Data { get; set; }
    public IEnumerable<TimeLineEntry> Timeline { get; set; } 
    public string ChartData { get; set; }
}

In my controller, I'm passing this model to the view as an ActionResult:

    public ActionResult Summary(FilterModel filter)
    {
        var modelData = GetModelData(filter);

        var timeline = BuildTimeLine(modelData);

        var chartData = BuildChartData(timeline);

        MyModel model = new MyModel
        {
            ModelData = modelData,
            Timeline = timeline,
            ChartData = chartData
        };

        return View(model); //setting a breakpoint here, ChartData JSON looks 
    }

    private string BuildChartData(List<TimelineEntry> data)
    {
        var timeline = data.Select(a => new
        {
            content = a.Description,
            start = a.CreatedOn
        });

        var jsonSerializer = new JavaScriptSerializer();
        return jsonSerializer.Serialize(timeline);
    }

In the view, I'm attempting to create a variable to store the JSON for use in the javascript application, like the following:

<script type="text/javascript">
  // DOM element for the timeline
    var container = document.getElementById('visualization');

    var data = @Model.ChartData; //I have a feeling I can't define data like this due to the way it is compiled.

    var chartData = JSON.parse(data);
    var items = new vis.DataSet(chartData); //this takes JSON

  var options = {};

  var timeline = new vis.Timeline(container, items, options);
</script>

When the page is compiled, I'm getting a javascript error: Uncaught SyntaxError: Unexpected token &

This happens when I try to store @Model.ChartData as a variable; it looks like this when compiled: [{&quot;content&quot;:&quot;&quot;,&quot;start&quot;:&quot;\/Date(1471890279333)\/&quot;},{ ....

I feel like this is a simple problem, but I'm currently at a loss as to how to properly pass the JSON from model into the view.

3
  • 1
    var data = @Html.Raw(Json,Encode(Model.ChartData)) Commented Sep 1, 2016 at 22:16
  • @StephenMuecke brilliant, thanks. Just to capture a slight typo, this fix worked: var data = @Html.Raw(Json.Encode(Model.ChartData)) Commented Sep 1, 2016 at 22:23
  • Fat fingers :). You might also want to consider formatting the date on the server if you want it in that format (e.g CreatedOn.ToString("yyyy-MM-dd")) Commented Sep 1, 2016 at 22:26

1 Answer 1

1

In the script you can use

var data = @Html.Raw(Json.Encode(Model.ChartData))

however, your wanting an array of objects in the client, which you already have in the controller, so there is little point serializing your collection to a string in the controller and then converting it back to a collection on the client.

Your controller can simply be

public ActionResult Summary(FilterModel filter)
{
    var modelData = GetModelData(filter);
    var timeline = BuildTimeLine(modelData);
    var chartData = BuildChartData(timeline);

    MyModel model = new MyModel
    {
        ModelData = modelData,
        Timeline = timeline,
        ChartData = chartData.Select(a => new ChartDataVM
        {
            content = a.Description,
            start = a.CreatedOn
        })
    };
    return View(model); 
}

where property ChartData is public IEnumerable<ChartDataVM> ChartData { get; set; }, andChartDataVM` is

public class ChartDataVM
{
    public string content { get; set; }
    public DateTime start { get; set; }
}

Then in the view, its

var data = @Html.Raw(Json.Encode(Model.ChartData));
// var chartData = JSON.parse(data); Not required
var items = new vis.DataSet(data);

However, based on the format you have indicated that the plugin requires, you may need to change property start to typeof string and in the query use

start = a.CreatedOn.Tostring("yyyy-MM-dd")
Sign up to request clarification or add additional context in comments.

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.