I already check this post
I have a similar problem
I have a variable object with attributes others objects
so I Have the main object and I want put null to one of their properties
I tried this options but they fail of course, before each line I put the error that give me
set object.other = null
--------------------------------------
Unexpected token "punctuation" of value "." ("end of statement block" expected)
set object["other"] = null
--------------------------------------
Unexpected token "punctuation" of value "[" ("end of statement block" expected)
set (object, 'other', null)
--------------------------------------
Only variables can be assigned to. Unexpected token "punctuation" of value "(" ("name" expected)
set object = object|merge({'other',null})
--------------------------------------
The merge filter only works with arrays or "Traversable", got "object" as first argument
Please Help
The first three of your examples are not valid Twig syntax, like the error messages say.
The fourth example, using Twig's merge filter, would work if your object was an array, a hash (i.e. {% set object = { other: 'something' } %}), or an instance of a Traversable class. Your object is none of these, as can be seen from the error message returned by Twig: 'The merge filter only works with arrays or "Traversable", got "object" as first argument.' Note also that you have a typo (as already mentioned by aferber): you have {'other', null} whereas you should have {'other': null} (or {other: null}).
Thus, what you are trying to do can't be done out-of-the-box in Twig. You need to either modify your class (e.g. create a method which sets the other property to null) or create a Twig extension. The question Adding a property to an object in twig has answers showing how you could approach these solutions.
A third possibility would be to modify your class so that the object is Traversable. Then you could use the merge filter.
Of course one more possibility is to stop trying to do this in Twig and do this e.g. in a controller (as already suggested by Frank B).
In order for this to work, object has to be an object in the first place. The error message to your last try (merge filter) clearly shows this isn't the case (in PHP, every object is Traversable). In addition, the object has to have a public property named other.
You should also pay attention to the difference between {'other',null} and {'other': null}.
After you have fixed all those problem (ie. made sure you assign an object to object first), the merge filter will work, just as it did in the question you linked to.
Related
I actually solved my problem before posting, but I wonder if there are any better solutions?
Also if there is somewhere where there is a way to use list as-is?
I am writing a simple get endpoint if F# which needs to accept a list of strings as an argument.
I take that list as the input to a query that runs as expected, I am not worried about that part.
The problem I am facing is as follows (minimal implmenetation):
When I define the endpoint as:
[<HttpGet>]
member _.Get() =
processStrings [ "test"; "test2" ]
it returns as expected.
When I change it to:
[<HttpGet>]
member _.Get([<FromQuery>] stringList: string list) = processStrings stringList
I get an error:
InvalidOperationException: Could not create an instance of type 'Microsoft.FSharp.Collections.FSharpList`1[[System.String, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Record types must have a single primary constructor. Alternatively, give the 'stringList' parameter a non-null default value.
Which doesn't make much sense to me, as I am using a list of strings, which in C# at least defaults to an empty list.
So I assume this comes down to how C# and F# interpret these signatures, but I am not sure how to resolve it.
I tried this signature and received the same error as above....
member _.Get( [<Optional; DefaultParameterValue([||]); FromQuery>] stringList: string list) = processStrings stringList
In the end using the following did solve the problem.
member _.Get( [<Optional; DefaultParameterValue([||]); FromQuery>] stringList: string seq) = processStrings stringList
I assume it was solved because seq is just IEnumerable, and then presumable list isn't just List from C# (mutable vs immutable). But is there a way to use an F# list in [FromQuery] parameters? Would [FromBody] have just worked? (No is the tested answer) Is there a way to add a type provider for an endpoint like this?
Is there something else I am missing here? Mine works now, but I am curious to the implications of the above.
I have not tested this, but I would assume that ASP.NET does not support F# lists as arguments. I would guess that taking the argument as an array would be much more likely to work:
[<HttpGet>]
member _.Get([<FromQuery>] stringList: string[]) =
processStrings (List.ofArray stringList)
I'm hoping to be able to analyze structured data stored in a custom dimension of a custom telemetry event emitted to application insights, and getting some weird behavior. It seems like the JSON can't be parsed normally, but if I pass it through strcat it is able to parse the json just fine.
customEvents
| where name == "PbConfigFilterComponentSaved"
| take 1
| project
jsonType=gettype(customDimensions.Json),
parsedType=gettype(parse_json(customDimensions.Json)),
strcatType=gettype(strcat('', customDimensions.Json)),
strcatParsedType=gettype(parse_json(strcat('', customDimensions.Json)))
Result:
jsonType: string
parsedType: string
strcatType: string
strcatParsedType: dictionary
Is there a better approach to getting parse_json to work on this kind of value?
Update
In case it's in any way relevant, here's the value of customDimensions.Json:
{"filterComponentKey":"CatalystAgeRange","typeKey":"TemporalConstraint","uiConfig":{"name":"Age","displayMode":"Age"},"config":{"dateSelector":"pat.BirthDTS"},"disabledForScenes":false,"disabledForFilters":false}
Could you please demonstrate a sample record that isn't parsed correctly?
Speculating (before seeing the data): Have you verified the final paragraph here doesn't apply to your case?
It is somewhat common to have a JSON string describing a property bag in which one of the "slots" is another JSON string. […] In such cases, it is not only necessary to invoke parse_json twice, but also to make sure that in the second call, tostring will be used. Otherwise, the second call to parse_json will simply pass-on the input to the output as-is, because its declared type is dynamic.
The type of customDimensions is dynamic and so accessing a property like customDimensions.json from it will return a string typed as dynamic.
You have to explicitly cast it as string and then parse it:
todynamic(tostring(customDimensions.json)).property
I think the "Notes" section in the documentation is exactly the issue, as mentioned by Yoni L. in the previous answer.
If I pass an Object into the model and test it with the "?is_string" built-in, it will falsely return a true value.
Is it possible (without checking the class name) to have a proper type checks on Objects?
FreeMarker: 2.3.28
Code to reproduce:
public class Test {}
// In Test Controller
ModelAndView mv = new ModelAndView("test");
mv.addObject("test", new Test());
// In test.ftl
<#if test?is_string>
${test} - is a string!
</#if>
// Result
Test#455b31c - is a string
The problem is that that approach isn't really supported by FreeMarker. The Java objects are mapped to some template language values via Configuration.objectWrapper, and the template only sees the result of that mapping. Furthermore the template language has a different type system than Java, a simplistic one, without classes. (It was a design goal back then that the data-model is just some simple tree, and the templates will work no mater what objects are behind, as far as it still gives the same tree.) ?is_... doesn't check the Java type, but the type according the template language. As with the usual ObjectWrapper-s a "generic" object (means, nothing recognized like List, Map, Date, etc.) can be used as a strings whose value is whatever toString() returns, it's a string as far as the template language is concerned. It's kind of duck typed...
A workaround I can think of is that first check the value with ?is_hash, as that will catch the said generic objects (as they support ., they are hashes as well, not just strings). Or instead just check the property you expect to be present in a Test. Then on the "else" branch you can continue with ?is_string.
I've got an object with a list defined inside it which points to a type that can be inherited. From what I understand MVC's default model binder will always instance the base type when reading data back in to this array from a form so by default I will have a list of base types.
So I need to use my own model binder and override CreateModel to instance a specific type (say from a hidden field). However when I do this and use
bindingContext.ValueProvider.GetValue("ModelType")
it always returns null even though through using fiddler I can see that form value Settings[0].ModelType contains my objects type and I need this value in CreateModel to instance the correct type.
Solved it. If your array objects need to be typed based on each item you need to use the following call to get "into" the array item
bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ModelType")
I'm not sure if this is the standard way to do it. If anyone has any better suggestions feel free to add them
I define a variable which is dynamicaly changes based on the user interactions, for example ID of an object sets to variable when user touches on it. After the ID sets I call a function in a custom component which is related to that object. Like this;
activeObject.videoPlay(event) ---> if the activeObject is video1 ---> video1.videoPlay(event) function will be called.
I tried several variable types when defining the variable activeObject, such as String , Array but didnt work out. By the way the data set to variable is String. When I use String type it gives this error;
Error #1061: Call to a possibly undefined method videoPlay through a reference with static type String.
Is there any way to use a string as a dynamic variable?
Is there any way to use a string as a dynamic variable?
Bracket notation -- obj["dynamicPropertyName"] as Type or in your case (activeObject['videoPlay'] as Function).apply(abc, [event]); You'll obviously want null object checks etc.