'Why is a string passed from JavaScript to Wasm always empty in section 4.2 of the Rust/Wasm beginner book?

I'm trying to follow the Rust WebAssembly book and I'm stuck at the exercise in section 4.2. I changed everything as described in the answer, but the given &str (name) in the greet function is always empty.

Here is my version of the greet function with debugging

#[wasm_bindgen]
pub fn greet(name: &str) {
    if name.len() == 0 {
        alert("NOT WORKING!");
    } else {
        alert(&format!("Hello, {}!", name));
    }
}

And the www/index.js file:

import * as wasm from "wasm-game-of-life";

wasm.greet("213");

Here is the generated function in pkg/wasm_game_of_life.js

/**
* @param {string} name
* @returns {void}
*/
export function greet(name) {
    const ptr0 = passStringToWasm(name);
    const len0 = WASM_VECTOR_LEN;
    try {
        return wasm.greet(ptr0, len0);

    } finally {
        wasm.__wbindgen_free(ptr0, len0 * 1);

    }

}

I get an alert popup with the text NOT WORKING!, but I expect Hello, 213! Why is my string empty? Is the book out of date or something? I deleted everything and started from scratch without luck...

I'm following the book, these are my first hours with WebAssembly.



Solution 1:[1]

I know it's probably late, but I ran into the same issue today and it's just like this. So, for anybody who hit this, here is the answer:

When you import import * as wasm from "wasm-game-of-life";, in wasm variable you have the module exported from the rust library. It contains greet method, but it's not one that is defined in the JS file, it's a C function which accepts two arguments, pointer to the string and it's length.

When you call wasm.greet() with a string param, you pass it to the C function, not to the JS function greet - that's why function call works but no string actually passed.

In order to call JS greet wrapper you have to import it explicitly (substitute with your js file paths):

import { default as wasm, greet } from "wasm-game-of-life"

wasm().then((module) => {
  module.greet("Test");  // this won't work, it's C/rust greet function
  console.log(module);
  greet("Test");  // this should work! it's js wrapper around C function
})

Solution 2:[2]

You would need to link the package, which is not stated in the original tutorial:

in wasm-game-of-life/pkg run

npm link  #or yarn link

then in wasm-game-of-life/www run

npm link wasm-game-of-life  #or yarn link wasm-game-of-life

reference: https://github.com/rustwasm/book/issues/144

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Antigluk
Solution 2 Megrax