LP13
LP13

Reputation: 34189

Dotliquid cannot bind property of an object inside an array

I have a .NET Core application that is using dotliquid. From the try online it looks like I can bind a property of an object that is inside an array. Like {{user.tasks[0].name}} where tasks is a collection of task object and name is property of the task.

I have JSON model that would be the input to the template. I don't know the JSON structure during the design time. So I am converting JSON string into ExpandoObject.

However, this does not work when I bind property of an object that is inside an array.

Demo NETFiddle

public class Program
{
    public static void Main()
    {   
        // this does not work       
        var modelString = "{\"States\": [{\"Name\": \"Texas\",\"Code\": \"TX\"}, {\"Name\": \"New York\",\"Code\": \"NY\"}]}";
        var template = "State Is:{{States[0].Name}}";   
        Render(modelString,template);
        
        //this works
        modelString = "{\"States\": [\"Texas\",\"New York\"]}";
        template = "State Is:{{States[0]}}";    
        Render(modelString,template);
    }
    
    private static void Render(string modelString, string template)
    {
        var model = JsonConvert.DeserializeObject<ExpandoObject>(modelString);
        var templateModel = Hash.FromDictionary(model);
        var html = Template.Parse(template).Render(templateModel);
        Console.WriteLine(html);    
    }
}

Upvotes: 0

Views: 799

Answers (1)

Michael Wang
Michael Wang

Reputation: 4030

You should parse as Dictionary<string, IEnumerable<ExpandoObject>> but not ExpandoObject.

using System;
using DotLiquid;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System.Dynamic;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // this does not work when binding a property of an object that is inside collection and when use dictionary
        var modelString = "{\"States\": [{\"Name\": \"Texas\",\"Code\": \"TX\"}, {\"Name\": \"New York\",\"Code\": \"NY\"}]}";
        var template = "State Is:{{Name}}";


        RenderFromDictionary(modelString, template);
    }

    private static void RenderFromDictionary(string modelString, string template)
    {
        var Stats = JsonConvert.DeserializeObject<Dictionary<string, IEnumerable<ExpandoObject>>>(modelString);
        foreach (ExpandoObject expandoObject in Stats["States"])
        {
            var templateModel = Hash.FromDictionary(expandoObject);
            var html = Template.Parse(template).Render(templateModel);
            Console.WriteLine(html);
        }
    }
}

Test Result:

enter image description here

Upvotes: 0

Related Questions