Reputation: 619
I'm following the simple example as in here to export a rust struct to a React TypeScript application :
#[wasm_bindgen]
pub struct Foo {
contents: u32,
}
#[wasm_bindgen]
impl Foo {
#[wasm_bindgen(constructor)]
pub fn new() -> Foo {
Foo { contents: 0 }
}
pub fn get_contents(&self) -> u32 {
self.contents
}
}
Then I add to App.tsx
the following
function App() {
let f = new Foo();
[...]
However when I run the react app I get : Uncaught TypeError: Cannot read properties of undefined (reading 'foo_new')
The struct is exported in module.js
as:
export class Foo {
static __wrap(ptr) {
const obj = Object.create(Foo.prototype);
obj.ptr = ptr;
return obj;
}
__destroy_into_raw() {
const ptr = this.ptr;
this.ptr = 0;
return ptr;
}
free() {
const ptr = this.__destroy_into_raw();
wasm.__wbg_foo_free(ptr);
}
/**
*/
constructor() {
const ret = wasm.foo_new(); <--- fails here
return Foo.__wrap(ret);
}
/**
* @returns {number}
*/
get_contents() {
const ret = wasm.__wbg_get_player_id(this.ptr);
return ret >>> 0;
}
}
and in module.d.ts
as:
export class Foo {
free(): void;
/**
*/
constructor();
/**
* @returns {number}
*/
get_contents(): number;
}
what am I missing?
Upvotes: 4
Views: 5337
Reputation: 720
I encounter the same error as you do. Uncaught TypeError: Cannot read properties of undefined (reading 'foo_new')
error indicates that your WASM library is not loaded. After reading the .js file generated by the WASM bindgen, I noticed that the wasm
object needs to be initialized which can be done via the init
function. Moreover, the init
function has been exported.
export { initSync }
export default init;
Therefore, the solution to your problem is to initialize the wasm
object through init
function before using Foo
.
Let's say the name of the Rust project is rust_wasm
, I do the following:
import rust_wasm_init from "rust_wasm";
import {Foo} from "rust_wasm";
async run_wasm_funcion() {
const path_to_wasm = "https://localhost:3000/static/js/rust_wasm.wasm"; //Remember to update the parameter in CopyPlugin
await rust_wasm_init(path_to_wasm); //This initializes the wasm object mentioned above
const foo = new Foo();
console.log(foo.get_contents());
}
Upvotes: 4