Israel Z Kollie
Israel Z Kollie

Reputation: 273

Exception while invoking method 'users.insert' Error: Match error: Expected array, got "admin" in field [0].roles Reading project metadata

I'm trying to insert user collection but getting the above error. Is there a way to make entry of a field into an array. It's expecting an array but I'm entering admin in the my role field. How can I insert the roles as an array from the UI?

This is the Server side, I'm defining all the fields that need to be inserted.

Meteor.methods({
  "users.insert"(users) {
    check(users, [
      {
        email: String,
        password: String,
        username: String,
        profile: {
          name: { firstname: String, lastname: String },
          phone: String
        },
        roles: [String]
      }
    ]);

    users.forEach(({ email, password, username, profile, roles }) => {
      const userExists = Accounts.findUserByEmail(email);

      if (!userExists) {
        const userId = Accounts.createUser({
          email,
          password,
          username,
          profile
        });
        Roles.addUsersToRoles(userId, roles, "default-group");
      }
    });
  }
});

The Client side, initial state and meteor call

this.state = {
      phone: "",
      email: "",
      password: "",
      username: "",
      roles: []
    };

onSubmit(e) {
    e.preventDefault();

    const {
      phone,
      email,
      password,
      username,
      roles
    } = this.state;

    const user = [
      {
        email,
        password,
        username,
        profile: {
          name: { firstname, lastname },
          phone,
        },
        roles
      }
    ];

    this.props.createUser("users.insert", user);
  }

The Submission Form, I'm inserting the values here

<form
          onSubmit={this.onSubmit.bind(this)}
          noValidate
          className="boxed-view__form"
        >
          <input
            className="editor__title editor__title--border"
            type="tel"
            name="phone"
            placeholder="Contact"
            value={this.state.phone}
            onChange={this.onChange}
          />
          <input
            className="editor__title"
            type="email"
            name="email"
            placeholder="Email"
            value={this.state.email}
            onChange={this.onChange}
          />
          <input
            className="editor__title"
            type="password"
            name="password"
            placeholder="Password"
            value={this.state.password}
            onChange={this.onChange}
          />
          <input
            className="editor__title"
            type="text"
            name="username"
            placeholder="username"
            value={this.state.username}
            onChange={this.onChange}
          />
          <input
            className="editor__title"
            type="text"
            name="roles"
            placeholder="Roles"
            value={!this.state.roles}
            onChange={this.onChange}
          />
          <button className="button">Create Account</button>
        </form>

Upvotes: 1

Views: 295

Answers (1)

Sean
Sean

Reputation: 2729

Although you are initialising the roles as an array in your state, you are overriding this when you type in the input and turning it in to a string.

To begin with roles = []

In your onChange function you are setting the roles in your state to be the string admin.

We are going to change the user object you create slightly so that instead of pushing a string it will push an array of all the words you type in the input so that you can type more than one role and they will all be applied

Here is the code that will do that:

roles.split(' ')

What this does is takes each word in the string you pass and makes it an element inside an array.

admin becomes ["admin"]

admin superuser becomes ["admin", "superuser"]

Here is the amended code that should work for you.

onSubmit(e) {
    e.preventDefault();

    const {
      phone,
      email,
      password,
      username,
      roles
    } = this.state;

    const user = [
      {
        email,
        password,
        username,
        profile: {
          name: { firstname, lastname },
          phone,
        },
        roles: roles.split(' '),
      }
    ];

    this.props.createUser("users.insert", user);
}

Upvotes: 2

Related Questions