Please help: moc compiler errors

Hello!

I am attempting to compile the following code

import Iter "mo:base/Iter";
import Map "mo:base/HashMap";
import Nat64 "mo:base/Nat64";
import Principal "mo:base/Principal";
import Text "mo:base/Text";

type UIDResult = {ok : Nat64; error : Text};

actor Landlord {
  var UserMap = Map.HashMap<Principal, Nat64>(10, Principal.equal, Principal.hash);
  stable var UserUpgradeStore : [(Principal, Nat64)] = [];
  stable var NextUID: Nat64 = 0;

  public func register(new_user : Principal) : async UIDResult {
     switch (UserMap.get(new_user)) {
      case null {
        NextUID += 1;
        UserMap.put(new_user, NextUID);
        let r : UIDResult = {ok: NextUID};
        return r;
      };
      case (?uid) { 
         let e : Text = "user is already registered as " # Nat64.toText(uid);
         let r : UIDResult = {error: e};
         return r;
      };
    }
  };

   system func preupgrade() {
      UserUpgradeStore := Iter.toArray(UserMap.entries());
   };

   system func postupgrade() {
      UserMap := Map.fromIter<Principal, Nat64>(UserUpgradeStore.vals(), 10, Principal.equal, Principal.hash);
      UserUpgradeStore := [];
   };
};

and get these errors:

src/landlord/landlord.mo:19.34-19.41: type error [M0029], unbound type NextUID
src/landlord/landlord.mo:24.38-24.39: type error [M0029], unbound type e

How do I resolve these?

Okay … I had some simple syntax errors in the code above.
This compiles:

import Iter "mo:base/Iter";
import Map "mo:base/HashMap";
import Nat64 "mo:base/Nat64";
import Principal "mo:base/Principal";
import Text "mo:base/Text";

actor {
  type UIDResult = {ok : Nat64; error : Text};
  var UserMap = Map.HashMap<Principal, Nat64>(10, Principal.equal, Principal.hash);
  stable var UserUpgradeStore : [(Principal, Nat64)] = [];
  stable var NextUID: Nat64 = 0;

  public func register(new_user : Principal) : async UIDResult {
     switch (UserMap.get(new_user)) {
      case null {
        NextUID += 1;
        UserMap.put(new_user, NextUID);
        let r : UIDResult = {ok = NextUID; error = ""};
        return r;
      };
      case (?uid) { 
         let e : Text = "user is already registered as " # Nat64.toText(uid);
         let r : UIDResult = {error = e; ok = 0};
         return r;
      };
    }
  };

   system func preupgrade() {
      UserUpgradeStore := Iter.toArray(UserMap.entries());
   };

   system func postupgrade() {
      UserMap := Map.fromIter<Principal, Nat64>(UserUpgradeStore.vals(), 10, Principal.equal, Principal.hash);
      UserUpgradeStore := [];
   };
};

Thanks for your help @mariop !!

I would like to convert UIDResult to a variant … any suggestions what that would look like?

You can use Result | Internet Computer Home for such purpose.

   import Result "mo:base/Result";
    ...
   public func register(new_user : Principal) : async Result.Result<Nat64, Text> {
     switch (UserMap.get(new_user)) {
      case null {
        NextUID += 1;
        UserMap.put(new_user, NextUID);
        return #ok NextUID;
      };
      case (?uid) { 
         let e : Text = "user is already registered as " # Nat64.toText(uid);
         return #err e;
      };
    }
  };
1 Like

Thank you very much indeed! Will adopt the solution suggested.

1 Like