Skip to content

Type Error when using mixed type dictionaries and numeric_inputs. #34

@raven-black-dream

Description

@raven-black-dream

Describe the bug

NumberInput (number_input) gives an error:

"TypeError: Invalid var passed for prop value, expected type <class 'str'>, got value _["reps"] of type typing.Any."

When using a state variable which returns a dictionary of mixed types. Given that the required type annotations only really allow a single type annotation for dictionaries. Dict[str, str] for example being a dictionary where the keys and values are all strings.

To Reproduce

Create a state variable which returns a dictionary with mixed types and provide the type annotation Dict[str, Any].

Create a form which requires both text elements and numeric inputs.

Try to use the state variable's values to set the initial values for the form.

  • Code/Link to Repo:
@rx.var
    def items(self) -> List[Dict[str, Any]]:
        preds = [pred for pred in self.user_program['predictions'] if pred['day_name'] == self.day_name]
        items = []
        if self.day == [{}]:
            return [{}]
        for item in self.day:
            exercise_name = item['exercise'] if not item['myoreps'] else f"{item['exercise']}-myoreps"
            exercise_pred = [exercise for exercise in preds if exercise['exercise'] == item['exercise']][0]
            for i in range(item['num_sets']):
                if i + 1 == item['num_sets'] and item['amrap']:
                    items.append(
                        {
                            'exercise_name': exercise_name,
                            'input_id_reps': f"{item['exercise']}_i_reps",
                            'input_id_weight': f"{item['exercise']}_i_weight",
                            'input_id_rpe': f"{item['exercise']}_i_rpe",
                            'reps': item['min_reps'],
                            'weight': exercise_pred['weight'],
                            'unit': exercise_pred['unit'],
                            'rpe': 10.0
                        }
                    )
                else:
                    items.append(
                        {
                            'exercise_name': exercise_name,
                            'input_id_reps': f"{item['exercise']}_i_reps",
                            'input_id_weight': f"{item['exercise']}_i_weight",
                            'input_id_rpe': f"{item['exercise']}_i_rpe",
                            'reps': int(item['min_reps']),
                            'weight': float(exercise_pred['weight']),
                            'unit': exercise_pred['unit'],
                            'rpe': float(item['avg_rpe'])
                        }
                    )

        return items

def record_workout():
    return PageView([
        rx.heading("Record Workout", color='#aaaaaa', font_size="2em"),
        rx.center(rx.form(
            rx.vstack(
                rx.hstack(
                    rx.box(rx.text("Exercise"), width='20%', bg_color='#1a472a', color='#ffffff',
                           border_radius="md"),
                    rx.box(rx.text("Reps"), width='20%', bg_color='#1a472a', color='#ffffff',
                           border_radius="md"),
                    rx.box(rx.text("Weight"), width='20%', bg_color='#1a472a', color='#ffffff',
                           border_radius="md"),
                    rx.box(rx.text("RPE"), width='20%', bg_color='#1a472a', color='#ffffff',
                           border_radius="md"),
                    width='100%'
                ),
                rx.foreach(
                    WorkoutFormState.items,
                    lambda item: rx.hstack(
                        rx.box(rx.text(item['exercise_name']), width='20%', bg_color='#1a472a',
                               color='#ffffff', border_radius="md"),
                        rx.number_input(value=item['reps'], id=item["input_id_reps"], size='sm', width='20%'),
                        rx.number_input(value=item['weight'], input_mode='decimal',
                                 id=item["input_id_weight"], size='sm', width='20%'),
                        rx.number_input(value=item['rpe'], input_mode='decimal',
                                 id=item["input_id_rpe"], size='sm', width='20%'),
                        width='100%'


                    )
                )
            ),

            rx.button("Submit", type_="submit", color_scheme='green'),
            on_submit=WorkoutFormState.submit,
        ))
    ]).build()

Expected behavior

Page should render with NumberInputs where they should be in the form.

Screenshots
If applicable, add screenshots to help explain your problem.

Specifics (please complete the following information):

  • Python Version: 3.11
  • Reflex Version: 2.0.9
  • OS: Ubuntu 22.04.03 LTS
  • Browser (Optional): Chrome

Additional context

I am working around the issue by using regular inputs, and casting the numeric values to strings, then will be casting them back to numeric values before writing to the database.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions