Store array in form slot

Hey guys!

I have a form with a slot which should contain more than one value. e.g. i want to collect all hobbies or interests of a user using that form. When a slot is set in a form it goes on with the next slot but i want it to stay at this specific slot and add more items to the slot “interests”. Should i set the slot to “list” in the domain file?

 slots:
   interests:
     type: list
     auto_fill: false

Lets say i have an intent “interest”

## intent:interest
- my hobby is {interests}
- one of my hobbies is {interests}
- another of my interests is {interests}
- i love doing {interests}
- i like {interests}

And my happypath is

## happy path
* greet
 - process_form
 - form{"name": "process_form"}
 - form{"name": null}
 - utter_slots_values
* goodbye
 - utter_goodbye

How can i continue asking the user for more interests until he is done? And how can i store more than one value in the slot? Like in an array?

Hi @spokey,

Method 1: Entities extracted from nlu.md and stored in the slot list, I implemented this with custom action.

This also works with FormAction

.

Method 2: Manually user enter one by one in slot. This uses self.from_text() no entity extraction will happen here.

    def validate_cusine(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:

      
        if len(val) < 3:
            print('Still Not finished')
            val.append(value)
            print("C", val)
            return{'cusine': None}
        else:
            return{"cusine": val}

you have to write validate function for interests and create a list variable in python, here I created list as val. Then change in the if condition to lets say you want to get 5 hobbies from user check for len(5) or even you can check for particular word from user That's It or done. To end storing values in slot.

How this will work. I am not ending my form action here, till I get 3 cuisines from user I keep on asking the user for input. Then I return the slot from validate method and then the controls are passed to submit method and that will end the form action

This will act like storing values in array or list

1 Like

Hi Spokey! One solution would be to define two separate slots, one for identifying individual user interests / hobbies and another to maintain the aggregated list of interests they’ve provided.

entities:
- interest
slots:
    interest:
      type: unfeaturized
    interest_list:
      type: list

The validation function for interest would append values to the interest_list slot.

To get the form to continue appending items to the interest_list, you can create a boolean confirm slot and map it to a finished intent so that the form stays activated until the user says they’re finished.

The confirm slot would need to be added to the list of required slots, and the slot mapping would look something like:

        "confirm": [
            self.from_intent(value=True, intent="finished")
        ],

@MuraliChandran14 Can you please elaborate the method 2?