0
votes

I am a bit stuck on this, don't even know if it is entirely possible. Searching the web I came across posts like this one by Joe Mayo: http://mayoster.blogspot.com.es/2016/05/dynamic-formflow-forms-in-bot-builder.html where he explains how to use Dynamic Fields instead of pre-defined enums.

So far so good, the real question comes when the values are not "defined somewhere", but instead depend on a previous answer of the FormFlow. Is this possible? (Considering that the Form Build is done all at once?

Example:

public static IForm<ItemQueue> BuildForm()
    {

        return new FormBuilder<ItemQueue>()                
            .Field(nameof(ItemQueue.ItemFamily))
            .Field(nameof(ItemQueue.ItemType))
            .Field(new FieldReflector<ItemQueue>(nameof(ItemGroup))
                .SetType(null)
                .SetDefine((state, field) =>
                {
                    List<string> groupList= GetItemGroups(//PREVIOUS ANSWER HERE);

                    foreach (var group in groupList)
                        field
                             .AddDescription(module, module)
                             .AddTerms(module, module);
                    return Task.FromResult(true);

                }))
            .AddRemainingFields()
            .Build()
            ;
    }

Where the "//PREVIOUS ANSWER HERE" part determines the zone were the string should be loaded. Tried everything I could think of and searched around with no success, mostly because it is executed as a single step.

Based on some opinions apparently one option is to, after I get the answer I want, start a new FormFlow with the stored value, but does not seem like the cleanest way to do this.

I really appreciate any help on the matter.

Thanks in advance.

1

1 Answers

0
votes

Finally figured it out!

Ends up that you can go for the state of the previous fields and send that (as a string, for example) to a new function:

public static IForm<ItemQueue> BuildForm()
{

    return new FormBuilder<ItemQueue>()                
        .Field(nameof(ItemQueue.ItemFamily))
        .Field(nameof(ItemQueue.ItemType))
        .Field(new FieldReflector<ItemQueue>(nameof(ItemGroup))
            .SetType(null)
            .SetDefine((state, field) =>
            {
                List<string> groupList= GetItemGroups(state.ItemType.ToString());

                foreach (var group in groupList)
                    field
                         .AddDescription(module, module)
                         .AddTerms(module, module);
                return Task.FromResult(true);

            }))
        .AddRemainingFields()
        .Build()
        ;
}

However, you have to beware the fact that the value will only be "usable" for the next field (if it exists) after it enters the {Get; Set;}. Otherwise it will remain null.

That is, in my example I can get ItemType Value because, before executing the ItemGroup Field it already defined the value for the previous one.

Outside of the .Field overrides, if you want to call it .OnCompletion you have to do it from the "field" property.