How to handle null values from javascript into rust through webassembly?. I am practising rust + webassembly by making todo list

**# This is the rust code:**
use wasm_bindgen::prelude::*;
use js_sys::Array;

#[wasm_bindgen]
pub struct Task {
id: u32,
title: String,
completed: bool,
}

#[wasm_bindgen]
impl Task {
#[wasm_bindgen(constructor)]
pub fn new(id: u32, title: String) -> Task {
Task {
id,
title,
completed: false,
}
}

pub fn get_id(&self) -> u32 {
    self.id
}

pub fn get_title(&self) -> String {
    self.title.clone()
}

pub fn is_completed(&self) -> bool {
    self.completed
}

pub fn toggle_completed(&mut self) {
    self.completed = !self.completed;
}

// Convert Task to JS object
pub fn to_js(&self) -> JsValue {
    let obj = js_sys::Object::new();
    
    js_sys::Reflect::set(&obj, &"id".into(), &JsValue::from(self.id)).unwrap();
    js_sys::Reflect::set(&obj, &"title".into(), &JsValue::from(&self.title)).unwrap();
    js_sys::Reflect::set(&obj, &"completed".into(), &JsValue::from(self.completed)).unwrap();
    
    obj.into()
}

}

#[wasm_bindgen]
pub struct TaskManager {
tasks: Vec,
}

#[wasm_bindgen]
impl TaskManager {
#[wasm_bindgen(constructor)]
pub fn new() -> TaskManager {
TaskManager {
tasks: Vec::new(),
}
}

pub fn add_task(&mut self, title: String) {
    let id = self.tasks.len() as u32 + 1;
    let task = Task::new(id, title);
    self.tasks.push(task);
}

pub fn remove_task(&mut self, id: u32) {
    self.tasks.retain(|task| task.get_id() != id);
}

pub fn toggle_task_completion(&mut self, id: u32) {
    if let Some(task) = self.tasks.iter_mut().find(|task| task.get_id() == id) {
        task.toggle_completed();
    }
}

// Updated get_tasks method to use to_js()
pub fn get_tasks(&self) -> Array {
    let arr = Array::new();
    for task in &self.tasks {
        arr.push(&task.to_js());
    }
    arr
}

}
This is javascript code:
import init, { Task, TaskManager } from '../pkg/my_todo_app.js';

async function run() {
await init();
const taskManager = new TaskManager();

const addButton = document.getElementById('add-task-btn');
const taskTitleInput = document.getElementById('task-title');
const taskList = document.getElementById('task-list');

function updateTaskList() {
    taskList.innerHTML = '';
    const tasks = taskManager.get_tasks();
    tasks.forEach(task => {
        const taskElement = document.createElement('li');
        taskElement.textContent = `${task.title} - ${task.completed ? 'Completed' : 'Incomplete'}`;
        taskList.appendChild(taskElement);
    });
}

addButton.addEventListener('click', () => {
    const taskTitle = taskTitleInput.value.trim();
    if (taskTitle) {
        taskManager.add_task(taskTitle);
        taskTitleInput.value = '';
        updateTaskList();
    }
});

}

run();

Btw this works.i am asking is there any better way to do this without usind js_sys

Currently, in your code, null will never be passed into rust. The only code that passes data directly from JS to rust is wrapped in a check:

    if (taskTitle) {
        taskManager.add_task(taskTitle);
        //...
    }

And taskTitle itself is the value of an input which will always be a string (either something, or empty string), so even without the check it will not be null.

You could also use typescript with well defined types for further assurance.

Otherwise, I am not knowledgable enough but am also curious if there is a way to make the title paramater of Task::new an Option<String> instead of just String such that a null value passed in would become None