Skip to content
JPVenson edited this page Aug 12, 2022 · 3 revisions

What does "is used like an array by the template, but is a scalar value or object in your model" mean?

This runtime error will throw if you try to iterate an object with the #each keyword. #each does only work with collections of objects.

How to fix

What are you trying to do? Do you want to iterate over all properties of the object? Then use the every (.?) Keyword. Otherwise check your property, it must inhert from IEnumerable.

My formatter is not called

If you create a custom formatter but it is not called you can take the following steps to ensure that everything is correctly setup:

  • Check if you added your formatter via 'ParserOptionsBuilder.WithFormatter(Delegate, Name)' or 'ParserOptionsBuilder.WithFormatters(Type)' to the ParserOptionsBuilder
  • If you are using 'WithFormatters' ensure your formatter is attributed with 'MorestachioFormatterAttribute' and the name matches (check casing!)
  • Check your argument types. The type must ether exactly match or be a base type of the object you want to format.
  • Check for nulls in your path. If there is a Null value along the property path on the source object like Data.OtherData.NullValue.Value.Formatter() where NullValue is null, the formatter will not be called.
  • If you are using custom services, check that the argument is attributed with the ExternalDataAttribute and your service is added via ParserOptionsBuilder.WithService(Type, Name)

using the root keyword (~) makes problems with formatters

When using the root keyword, the whole path following that keyword will be executed in the scope of the root object. That means if you use the keyword, and then execute an formatter on a path of the root, even the arguments will start at the root:

{{~subOfRoot.FormatterName(alsoInRoot.OtherFormatter(), someWhereInCurrentContext)}}

the path alsoInRoot will in that case be the same as you would write ~alsoInRoot as the whole path is scoped to root with the ~ keyword therefor someWhereInCurrentContext that is releative to the current context canno be resolved.

How to fix

If that is a problem, you have to ether store the current context in a variable or get the root object and store it:

//ether store the root object in variable
{{#var root = ~subOfRoot}}
{{root.FormatterName(~alsoInRoot.OtherFormatter(), someWhereInCurrentContext)}}
//or store the current context somewhere
{{#var that = this}}
{{~subOfRoot.FormatterName(alsoInRoot.OtherFormatter(), that.someWhereInCurrentContext)}}