Ines
Ines

Reputation: 61

Unable to switch between dialogs in Bot Framework v4

I'm having some trouble moving around from one dialog to another in Bot Framework v4. What I want to accomplish is to move from say, dialog X to Y and then from Y back to X.

So for instance, I have a GetShoppingCart dialog and I want to switch to the FindRecipe dialog. I've tried adding the FindRecipe dialog (dc.Dialogs.Add(FindRecipeDialog.Id, recipe_dialog);) to the GetShoppingCart's waterfall, but as soon as I do the same thing in the FindRecipe dialog, there's an infinite loop. This is troublesome since I need to add this line in order to access the dialog's destination id. Otherwise it will not be recongized when called by the Replace method (await dc.Replace(FindRecipeDialog.Id, dialogArgs);).

I then tried to pass the dialogs object from the root dialog to both FindRecipe and GetShoppingCart dialogs and did the following in the GetShoppingCart dialog:

IDialog recipe_dialog = dialogs.Find(FindRecipeDialog.Id);
dc.Dialogs.Add(FindRecipeDialog.Id, recipe_dialog);
await dc.Replace(FindRecipeDialog.Id, dialogArgs);

With this I was able to successfully enter the FindRecipe dialog, without creating the infinite loop. In the FindRecipe dialog it performs the first watterfall step:

async(dc, args, next) =>
{
    UserStateObject newUserStateObject;
    var userState = UserState<UserState>.Get(dc.Context);
    UserStateObject userStateObject = JsonConvert.DeserializeObject<UserStateObject>(userState.UserStateObject);
    if (args == null) {
        await FindRecipe(dc);
    } else {
        newUserStateObject = args["userState"] as UserStateObject;
        if(newUserStateObject.UserInputs.UserRecipeChoices == RecipeUserChoicesEnum.AddAnotherProductChoice) 
            await AddOtherProductChoice(dc, userStateObject);
    }
}

However, right after finishing just one method, it goes back to the GetShoppingCart dialog, even though there are still waterfall steps left in the FindRecipe dialog. In the following turn it throws this exception, when trying to perform "context.Continue()";

{System.Exception: DialogSet.continue(): Can't continue dialog. A dialog with an id of 'FindRecipe' wasn't found.   at Microsoft.Bot.Builder.Dialogs.DialogContext.Continue()   at Microsoft.Bot.Builder.Dialogs.DialogContainer.DialogContinue(DialogContext dc)   at Microsoft.Bot.Builder.Dialogs.DialogContext.Continue()   at RecipeBot.RecipesBot.OnTurn(ITurnContext context) ... }

Do I need to add the FindRecipe dialog to dc.Dialogs again at some point?

I've tried it right before dc.continue() (where the exception is thrown), but in this case it throws:

{System.Exception: DialogSet.add(): A dialog with an id of 'FindRecipe' already added.   at Microsoft.Bot.Builder.Dialogs.DialogSet.Add(String dialogId, IDialog dialog)   at RecipeBot.RecipesBot.OnTurn(ITurnContext context) ... }

Upvotes: 2

Views: 2596

Answers (1)

Ines
Ines

Reputation: 61

I was able to fix this problem.

I was creating a new dialogue every time a message was received and this was causing the problem:

 dialogs = new DialogSet();
 dialogs.Add(GetShoppingCartDialog.Id, new GetShoppingCartDialog());
 dialogs.Add(FindRecipeDialog.Id, new FindRecipeDialog());

To fix it I used a singleton: created an instance of each dialog and saved it as a variable of the dialog.

 dialogs = new DialogSet();
 dialogs.Add(GetShoppingCartDialog.Id, GetShoppingCartDialog.Instance);
 dialogs.Add(FindRecipeDialog.Id, FindRecipeDialog.Instance);

Upvotes: 4

Related Questions