How to get UserProfile in another Dialogio

Viewed 32

I'm implementing a chatbot using microsoft's bot builder.

When I've implemented an alternate route to the dialog, I'm losing the user's Profile references.

my main dialogue

import { StatePropertyAccessor, UserState, TurnContext } from 'botbuilder';
import { ChoiceFactory, ChoicePrompt, ComponentDialog, ConfirmPrompt, DialogSet, DialogTurnStatus, NumberPrompt, PromptValidatorContext, TextPrompt, WaterfallDialog, WaterfallStepContext } from 'botbuilder-dialogs';
import { UserProfile } from './UserprofileModel';
import {OtherDialog, OTHER_DIALOG} from './OtherDialogs'

const USER_PROFILE = 'USER_PROFILE';
const NAME_PROMPT = 'NAME_PROMPT';
const INPUT_PROMPT = 'INPUT_PROMPT';
const WATERFALL_DIALOG = 'WATERFALL_DIALOG';
const CONFIRM_PROMP = 'CONFIRM_PROMP';
const NUMBER_PROMPT = 'NUMBER_PROMPT';
const CHOISE_PROMPT = 'CHOISE_PROMPT';
export class UserProfileData extends ComponentDialog {
  private userProfile: StatePropertyAccessor<UserProfile>;

  constructor(userState: UserState) {
    super('userProfileData');

    this.userProfile = userState.createProperty(USER_PROFILE);

    this.addDialog(new TextPrompt(NAME_PROMPT))
    this.addDialog(new TextPrompt(INPUT_PROMPT))
    this.addDialog(new ConfirmPrompt(CONFIRM_PROMP))
    this.addDialog(new ChoicePrompt(CHOISE_PROMPT))

    this.addDialog(new OtherDialog(userState));

    this.addDialog(new WaterfallDialog(WATERFALL_DIALOG, [
      this.nameStep.bind(this),
      this.nameConfirmStep.bind(this),
      this.typeInteraction.bind(this),
      this.finshStep.bind(this)
    ]));

    this.initialDialogId = WATERFALL_DIALOG;

  }

  public async run(turnContext: TurnContext, accessor: StatePropertyAccessor) {
    const dialogSet = new DialogSet(accessor);
    dialogSet.add(this);

    const dialogContext = await dialogSet.createContext(turnContext);
    const result = await dialogContext.continueDialog();
    if (result.status === DialogTurnStatus.empty) {
      await dialogContext.beginDialog(this.id);
    }
  }

  private async nameStep(stepContext: WaterfallStepContext<UserProfile>) {
    return await stepContext.prompt(NAME_PROMPT, 'What is your name?');
  }

  private async nameConfirmStep(stepContext: WaterfallStepContext<UserProfile>) {
    stepContext.options.name = stepContext.result;

    await stepContext.context.sendActivity(`Olá ${stepContext.result}!`);
    
    return await stepContext.prompt(INPUT_PROMPT, 'choice one number, 1, 2 or 3');
  }

  private async typeInteraction(stepContext: WaterfallStepContext<UserProfile>) {
    stepContext.options.type = stepContext.result;

    if (stepContext.options.type !== '1' && '2' && '3') {
      await stepContext.context.sendActivity(`ok`);
      await stepContext.context.sendActivity(`say something to the user.`);

      const userProfile = await this.userProfile.get(stepContext.context, new UserProfile());
      const stepContextOptions = stepContext.options;
      userProfile.name = stepContextOptions.name;
      console.log('------------- NAME ------------')
      console.log(userProfile.name)

      return await stepContext.beginDialog(OTHER_DIALOG)
    } else {
      await stepContext.context.sendActivity(`You choice ${stepContext.options.type}, So, go start.`);
    } 

    return stepContext.next();
  }

  private async finshStep(stepContext: WaterfallStepContext<UserProfile>) {

    await stepContext.context.sendActivity(`end of chat`);
    return await stepContext.endDialog();
  }

}

asdasd

My secondary dialog, where it should show the user's Profile. I'm trying to give a console.log on the name in the following function private async oneStep(stepContext: WaterfallStepContext)

import { StatePropertyAccessor, UserState, TurnContext } from 'botbuilder';
import { ChoiceFactory, ChoicePrompt, ComponentDialog, ConfirmPrompt, DialogSet, DialogTurnStatus, NumberPrompt, PromptValidatorContext, TextPrompt, WaterfallDialog, WaterfallStepContext } from 'botbuilder-dialogs';
import { UserProfile } from './UserprofileModel';
import { UserProfileData } from './userProfileDataCustom'

export const OTHER_DIALOG = 'OTHER_DIALOG';

const USER_PROFILE = 'USER_PROFILE';
const INPUT_PROMPT = 'INPUT_PROMPT';
const WATERFALL_DIALOG = 'WATERFALL_DIALOG';
export class OtherDialog extends ComponentDialog {
  private userProfile: StatePropertyAccessor<UserProfile>;

  constructor(userState: UserState) {
    super(OTHER_DIALOG);

    this.userProfile = userState.createProperty(USER_PROFILE);

    this.addDialog(new TextPrompt(INPUT_PROMPT))

    this.addDialog(new WaterfallDialog(WATERFALL_DIALOG, [
      this.oneStep.bind(this),
      this.twoStep.bind(this),
      this.treeStep.bind(this),
      this.fourStep.bind(this),
      this.finshStepOther.bind(this)
    ]));

    this.initialDialogId = WATERFALL_DIALOG;

  }

  private async oneStep(stepContext: WaterfallStepContext<UserProfile>) {

    console.log('------ NAME 2 --------');
    const userProfile = await this.userProfile.get(stepContext.context, new UserProfile());
    const stepContextOptions = stepContext.options;
    userProfile.name = stepContextOptions.name;
    console.log(userProfile.name)

    const name = 'SEM NOME'
    await stepContext.context.sendActivity(`Olá ${name}`);
    return await stepContext.prompt(INPUT_PROMPT, 'Input 1');
  }

  private async twoStep(stepContext: WaterfallStepContext<UserProfile>) {
    return await stepContext.prompt(INPUT_PROMPT, 'Input 2');
  }

  private async treeStep(stepContext: WaterfallStepContext<UserProfile>) {
    return await stepContext.prompt(INPUT_PROMPT, 'Input 3');
  }

  private async fourStep(stepContext: WaterfallStepContext<UserProfile>) {
    return await stepContext.prompt(INPUT_PROMPT, 'Input 4');
  }

  private async finshStepOther(stepContext: WaterfallStepContext<UserProfile>) {
    await stepContext.context.sendActivity(`ending other dialog`);
    return await stepContext.endDialog();
  }

}

asdasd

1 Answers

I made wrong decisions and was able to see in time.

I just set my context like this.

private async oneStep(stepContext: WaterfallStepContext<UserProfile>) {

    console.log('------ NAME 2 --------');
    const userProfile = await this.userProfile.get(stepContext.context, new UserProfile());
    // const stepContextOptions = stepContext.options;
    // userProfile.name = stepContextOptions.name;
    console.log(userProfile.name)

    const name = userProfile.name
    await stepContext.context.sendActivity(`Olá ${name}`);
    return await stepContext.prompt(INPUT_PROMPT, 'Input 1');
  }

I feel silly that the solution is so simple

Related