Slot value returns None

Hello, i’m trying to use FormAction to take in user information. When the user enters slot value the response returns None. Using cmd this is what i get. Can someone help Your input -> hi
hello what is your name? Your input -> john
Nice to meet you None

Domain file

slots:
  first_name:
    type: text

entities:
  - first_name

forms:
  - first_name_form

intents:
  - greet
  - affirm
  - deny
  - request_name
  - response
  

actions:
- utter_greet
- utter_affirm
- utter_deny
- utter_respond
- action_ask_name
- utter_request_name


    
templates:
  utter_greet:
  - text: 'hello what is your name?'

      
  utter_affirm:
  - text: 'Thats great!'
        
  utter_deny:
  - text: 'Thats too bad'
        

  utter_request_name:
  - text: "What is your name?"

  utter_respond:
  - text: "Nice to meet you {first_name}"

Stories.md

## happy path
* greet
  - utter_greet
* request_name
  - first_name_form
  - form{"name": "first_name_form"}
  - slot{"requested_slot": "first_name"}

* response
  - utter_respond


## sad path 1
* greet
  - utter_greet
* response
  - utter_respond


## sad path 2
* greet
  - utter_greet
* response
  - utter_respond


nlu.md

## intent:greet

- hey

- hello

- hi

- good morning

- good evening

- hey there

## intent:affirm

- yes

- indeed

- of course

- that sounds good

- correct

## intent:deny

- no

- never

- I don't think so

- don't like that

- no way

- not really

## intent: response

- my name is john

- john

- jack

- dennis

- jill

- mariah

- cosco

- mike

- pan

- steve

- carol

- tichalla

- natasha

- king

- tyler

- tom

- lizzy

- elizabeth

- noma

- lupita

- groot

- gendall

actions.py

class RegisterForm(FormAction): “”“Example of a custom form action”""

   def name(self):
       # type: () -> Text
       """Unique identifier of the form"""

       return "first_name_form"

   @staticmethod
   def required_slots(tracker):
       # type: () -> List[Text]
       """A list of required slots that the form has to fill"""

       return ["first_name"]

   def submit(self, dispatcher, tracker, domain):
       first_name = tracker.get_slot(first_name) 
       print("Name is",first_name)
       dispatcher.utter_template('utter_respond',first_name)
       return []

   def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
       """A dictionary to map required slots to
        - an extracted entity
        - intent: value pairs
        - a whole message
        or a list of them, where a first match will be picked"""
       return {
            "name": self.from_entity(entity="first_name", intent='request_name'),
          
    }
    
   def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
        """A dictionary to map required slots to
        - an extracted entity
        - intent: value pairs
        - a whole message
        or a list of them, where a first match will be picked"""
        return {
            "first_name": self.from_entity(entity="first_name"),
    }`Preformatted text`

Change utter_request_name to this:

templates:
  utter_ask_first_name:
  - text: 'hello what is your name?'

Template starts with utter_ask_, this means the form will use this to ask the slot.

I made a few changes to your form. You had two slot_mappings. You didn’t need the ‘name’. Also if you need to set more than one slot, you can do it in the same slot_mappings.

Using only self.from_text() means the form will take anything the user says to set this slot.

def name(self) -> Text:
    # type: () -> Text
    """Unique identifier of the form"""
    return 'first_name_form'

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    # type: () -> List[Text]
    return ['first_name']

def slot_mappings(self):
    # type: () -> Dict[Text: Union[Dict, List[Dict]]]
    return {'first_name': [self.from_text()]}

def submit(self,
               dispatcher: CollectingDispatcher,
               tracker: Tracker,
               domain: Dict[Text, Any],
    ) -> List[Dict]:
   return[]

Happy path should be:

## happy path
* greet
  - first_name_form
  - form{"name": "first_name_form"}
  - slot{"requested_slot": "first_name"}
  - utter_respond 
  1. Intent *greet triggers the form.
  2. The form will ask for the name.
  3. After the form bot will utter_respond and it will use the first_name in it.

Next time the user triggers the form, the bot will not ask for the name because it already has it.

Hi @Dnnsmoyo.

Looking at your code you have declared entities first_name in your domain.yml, But you have never mentioned in the nlu.md, Declaring entities next to your names will fix.

- [my name is john](first_name)
- [john](first_name)
- [jack](first_name)
- [dennis](first_name)
- [jill](first_name)
- [mariah](first_name)
- [cosco](first_name)
- [mike](first_name)
- [pan](first_name)

Murali

Thanks a lot, implementing your changes worked! Had to also add some code in happy path like:

happy path

  • greet
    • first_name_form
    • form{“name”: “first_name_form”}
    • slot{“requested_slot”: “first_name”}
    • slot{“first_name”: “john”}
      • slot{“first_name”: “jack”}
      • slot{“first_name”: “dennis”}
      • utter_respond

Your code worked for me thanks. Now first_name is recognized. Had to also edit other files, thanks!