Useraccounts: How to correctly check if a username already exists on sign-up?

I’m trying this for a couple of weeks now, but never got a working solution. Like described in the docs of the useraccounts package, I added an additional username field to my app, as a required field. I also want to check on signup whether the username has already been taken by another user.

This is my configuration:


if (Meteor.isServer) {
  Meteor.methods({
    "userExists": function(username) {
      check(username, String);
      var userExists = !!Meteor.users.findOne({
        username: username
      });
      return userExists;
    },
  });
}

var pwd = AccountsTemplates.removeField('password');
AccountsTemplates.removeField('email');
AccountsTemplates.addFields([{
    _id: "username",
    type: "text",
    displayName: "username",
    required: true,
    minLength: 3,
    func: function(value) {
      if (Meteor.isClient) {
        var self = this;
        //self.setValidating(true);
        Meteor.call("userExists", value, function(err, userExists) {
          app.dir({
            err: err,
            userExists: userExists
          });
          if (!userExists) {
            self.setSuccess();
          } else {
            self.setError(userExists);
          }
          self.setValidating(false);
        });
        return;
      }
      // Server
      if (Meteor.isServer) {
        return Meteor.call("userExists", value);
      }
    }
  }, {
    _id: 'email',
    type: 'email',
    required: true,
    displayName: "email",
    re: /.+@(.+){2,}\.(.+){2,}/,
    errStr: 'Invalid email',
  },
  pwd
]);

Validation of all the other fields (password, username) works as expected**, but validation of the username does not work correctly. The method is called on the server, and the client also receives the value correctly. But instead of showing the error in the signup form, the form state jumps back to signIn. (I’m using the standard combined signIn/signUp form, so the user has to click on “register” to signUp.)

I tried to self.setValidating(true) at the beginning of the func, as I was asuming this was missing in the docs, but this did not work either.

I’m quite sure I followed the docs word by word, but it just does not work as expected. So I have no idea what I might be missing?

** Actually, I’m also facing two other issues here:

  • If the email address has already been taken, the form also jumps back to the signIn state. But at least, it shows an appropriate error message there. I would expect that the form stays in signUp mode, since the error message relates to this state. EDIT: I could fix this by adding an explicit “signUp” route pointing to the same template, but do not know why this should be necessary.

  • If one of the other fields is invalid (e.g. the password is missing), the error message shows up on the signUp state (here it works correctly), but unfortunately in a language mix. The field is shown correctly (e.g. in German), but the actual error message is always shown in English. Sample: “Passwort (wiederholen): Required Field”. I would be happy if I could solve this as well, but the username validation is prio 1 for me, so I did not add another issue for the language problem yet.

@waldgeist This is how I do it:

Server:

Meteor.methods({
  doesUserExist(name) {
    return Accounts.findUserByUsername(name) != null;
  }
});

Client:

Meteor.call('doesUserExist', name, function(error, result) {
  // `result` is true if the user exists.
});

This is how I have it setup with React so as the user types, I set up an error message etc. :wink:

Thanks, but I meant “how to do it with the useraccounts package”.

Beats me :no_mouth:

Maybe someone with more knowledge can shed some light.

I’m getting result undefined on client side.