Format when passing an argument to motoko function

Hello everyone,

I am playing around with canisters and I have hit a roadblock when it comes to passing an argument from a javascript front-end to a motoko canister.

In the front-end the failling call is as follow:

api.mintNFT( {“to”: {“address” : “123456789123456789” } } ).then( response => {…

The problem is the formatting of the argument {“to”: {“address” : “123456789123456789” }}. For some reason, this format is rejected. I have tried a large number of variations such as without quotation, without brackets, different brackets, adding the word “record”, adding the word “variant”, removing “address”,etc. It is probably a silly mistake and I wonder if anyone could help. The biggest problem is that the rejection does not send an error back which makes it tedious to guess the problem…

The motoko target function is as follow:

public shared({ caller }) func mintNFT (request : MintRequest) : async () {
let recipient = ExtCore.User.toAID(request.to);
let token = nextTokenId;
ledger.put(token, recipient);
nextTokenId := nextTokenId + 1;
};

The type MintRequest is as follow:
public type MintRequest = {
to : ExtCore.User;
metadata : ?Blob;
};

The type user is as follow:
public type User = {
#address : AccountIdentifier; //No notification
#principal : Principal; //defaults to sub account 0
};

I can call it successfully from terminal in this format:
dfx canister call betadeck mintNFT “(record { to = variant { address = “123456789123456789” }; })”

I have successfully created and called other functions in the same canister, but never succeeded at passing any argument…

How do I pass arguments properly from javascript to motoko canister?

Many thanks in advance!!!

Have you try to provide an empty array for the optional value?

api.mintNFT( {“to”: {“address” : “123456789123456789”, metadata: [] } } ).

According my tests and discussed here, I think that optional values becomes mandatory array values on the frontend side.

If still doesn’t work, if you wrap your code with a try catch you do not get any errors in the console of the browser?

try {
   api.mintNFT(.....
} catch (err) {
   console.error(err);
}
4 Likes

Thank you so much @peterparker, both your suggestion were right!!

  1. I wrongly assumed that the metadata tag was optional, when actually it is the metadata argument that is optional.

  2. Reworking how to print the error allowed me to receive an error that was solved by adding “agent.fetchRootKey()”, see this post: Fail to verify certificate in development update calls

For people stumbling on this post, the final code looks like this:
api.mintNFT(({“to”: {“address” : “123456789123456789”}, “metadata”: })).then(res => {
console.log(“success”);
resolve(true);
}).catch(reject =>{
console.log(“The error is :”, reject);
});

Much gratitude for your help and the community!

6 Likes

The solution given is close but can’t be taken literally. You’re missing a bracket separating the "to" object and the "metadata" object. It should be :

api.mintNFT({"to": {"address" : "123456789123456789"}, "metadata": [] }).