How to add auto increment id to a HashMap?

Hello there,

I just started to code a blog with ICP and I’m following this tutorial.

The tutorial is a bit old and the recommendation is to create a HashMap instead of an Array of blog posts. I found the following code that works but I can’t figure it out how to add an auto increment in the HashMap instead of the Id as Text. Any pointers would be much appreciated.

    type Id = Text;

    type Entry = {
        author : Text;
        content : Text;
    };

    let entries = Map.HashMap<Id, Entry>(0, Text.equal, Text.hash);

    public func insert(id : Id, entry : Entry): async () {
        entries.put(id, entry);

    };
    public query func lookup(id : Id) : async ?Entry {
        entries.get(id)
    };
import Nat32 "mo:base/Nat32";
type Id = Nat32;

type Entry = {
    author : Text;
    content : Text;
};

let entries = Map.HashMap<Id, Entry>(0, Nat32.equal, func (a : Nat32) : Nat32 {a});
let nextEntryId : Id = 0;

public func insert(entry : Entry): async () {
    entries.put(nextEntryId, entry);
    nextEntryId++;
};
public query func lookup(id : Id) : async ?Entry {
    entries.get(id)
};

@stephenandrews thanks for the quick response.

It looks like this is not working ==> nextEntryId++;

unexpected token ';', expected one of token or <phrase> sequence:
  <exp_un(ob)>

I also added the following ( nextEntryId += 1; ) as I have seen in other examples but then I get this error:

type error [M0073], expected mutable assignment target

Sorry yeah +=1 is what you need to do.

Whopps my bad, switch it to a var then - defining it with let is immutable.

This works…thank you so much!!

Chur chur, welcome to the IC my friend!

Al the following functions are working except showEntries.

Do you know what am I missing? Sorry I’ve never worked with HashMaps

type Id = Nat32;

    type Entry = {
        author : Text;
        content : Text;
    };

    let entries = Map.HashMap<Id, Entry>(0, Nat32.equal, func (a : Nat32) : Nat32 {a});
    var nextEntryId : Id = 0;

    public func insert(entry : Entry): async () {
        entries.put(nextEntryId, entry);
        nextEntryId += 1;
    };
    public query func showSize () : async Nat {
        entries.size()
    };
    public query func lookup(id : Nat32) : async ?[Entry] {
        entries.get(id)
    };
    public query func showEntries () : async ?[Entry] {
        entries.entries()
    };

This is the error:

type error [M0096], expression of type
  ?Entry
cannot produce expected type
  ?[Entry]
/Users/fer/Projects/ic-projects/ic-playground/src/backend/blog/main.mo:33.9-33.26: type error [M0096], expression of type
  Iter/1<(Id, Entry)> = {next : () -> ?(Id, Entry)}
cannot produce expected type
  ?[Entry]

Do this instead:

public query func showEntries () : async [(Id, Entry)] {
    Iter.toArray(entries.entries());
};

Gives you both the ID and the Entry in a set of arrays. e.g.:

[
  [0, {...entry}], 
  ...
]
1 Like

I had a typo but I figure it out.

Thanks a lot again…It works!!!