Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Meteor.users create form (profile fields wont render) #200

Closed
odesey opened this issue Jun 2, 2014 · 19 comments
Closed

Nested Meteor.users create form (profile fields wont render) #200

odesey opened this issue Jun 2, 2014 · 19 comments

Comments

@odesey
Copy link

odesey commented Jun 2, 2014

I am trying to get autoform working with a nested Meteor.users schema and cant get the profile fields to show up.

I am using the example found here:
https://github.com/aldeed/meteor-collection2#attach-a-schema-to-meteorusers

I created a schema file here:

./collections/user.js

It has the following code:

    Schema = {};

    Schema.User = new SimpleSchema({
        _id: {
            type: String,
            regEx: SimpleSchema.RegEx.Id
        },
        emails: {
            type: [Object]
        },
        "emails.$.address": {
            type: String,
            regEx: SimpleSchema.RegEx.Email
        },
        "emails.$.verified": {
            type: Boolean
        }
        profile: {
            type: Schema.UserProfile,
        }
    });

    Schema.UserProfile = new SimpleSchema({
        firstName: {
            type: String,
            regEx: /^[a-zA-Z-]{2,25}$/,
        },
        lastName: {
            type: String,
            regEx: /^[a-zA-Z]{2,25}$/,
        },
        gender: {
            type: String,
            allowedValues: ['Male', 'Female'],
        }
    });


    Meteor.users.attachSchema(Schema.User);

In my template I have the following:

<template name="signupForm">
  <div class="panel-body">
    {{#autoForm schema=userSchema id="signupForm" type="insert"}}
    <fieldset>
        {{> afQuickField name='emails'}}
        {{> afFieldSelect name='profile.gender'}}

    </fieldset>
    <button type="submit" class="btn btn-primary">Insert</button>
    {{/autoForm}}
  </div>
</template>

I also tried:

{{#autoForm collection=users id="signupForm" type="insert"}}

Finally I created a helper like so:

Template.signupForm.helpers({
  users: function () {
    return Meteor.users;
  },
  userSchema: function () {
    return Schema.User;
  }
});

Is it possible to create a single form that would allow me to create a user with this type of nested schema?

Thanks.

@aldeed
Copy link
Collaborator

aldeed commented Jun 2, 2014

It should work with collection=users. You must use collection attribute rather than schema if doing type of insert/update/remove.

It is most likely because you are not including a required field (maybe firstName and lastName, looking at your form). You can set SimpleSchema.debug = true in client code to see logging of any validation errors. Any required fields must be included or made optional.

Also, if your form includes a password, it would be better to use an onSubmit hook with the form, and in the hook, call Accounts.createUser() to create the user, and then return false. This will ensure that the password isn't sent across the wire in plain text. (I'm not sure if a direct insert on the client is smart enough to secure the password field.)

@odesey
Copy link
Author

odesey commented Jun 2, 2014

I switched to using collection=users and here are the results:

{{> afQuickField name='email'}} --> this field works and has always displayed properly

these 3 fields however:

 {{> afQuickField name='users.firstName'}}
 {{> afQuickField name='users.lastName'}}
 {{> afQuickField name='users.gender'}}

the page fails to load and a console.log error is displayed:

Exception from Deps recompute function: Error: Invalid field name: users.firstName

If I switch the fields as follows:

{{> afObjectField name='users.firstName'}}
{{> afObjectField name='users.lastName'}}
{{> afObjectField name='users.gender'}}

The page loads, there are no errors but the fields are missing.

I will try enabling debugging mode and see if it provides any additional info.

@aldeed
Copy link
Collaborator

aldeed commented Jun 2, 2014

Shouldn't it be profile.firstName?

Also, for afObjectField, the name should be a field that takes an Object, so:

{{> afObjectField name='profile'}}

And it will render inputs for all the properties in that object.

@odesey
Copy link
Author

odesey commented Jun 2, 2014

{{> afObjectField name='profile'}} doesnt do anything, I actually tried this prior to posting and forgot to include it in my original comment

{{> afObjectField name='profile.firstName'}} does nothing like {{> afObjectField name='profile'}}

{{> afQuickField name='profile.firstName'}} generates the following error:

Exception from Deps recompute function: Error: Invalid field name: profile.firstName

Thanks for the suggestions!

I am wondering if what I am trying to do is even possible/supported?

Maybe I have to create a separate form for the Meteor.user().profile properties?

@aldeed
Copy link
Collaborator

aldeed commented Jun 3, 2014

I don't know why those would not work. Are you able to provide a link to an example repo demonstrating the issue?

@odesey
Copy link
Author

odesey commented Jun 3, 2014

Here's the repo with the example project.

https://github.com/odesey/autoform-test

@afuggini
Copy link

afuggini commented Jun 3, 2014

@aldeed Thanks for the help, I've found a similar issue and had to find a workaround cause I couldn't insert/update users either.

I'm trying your suggested collection=users and what I get is error:

Exception from Deps recompute function: Error: AutoForm: form with id "userProfileForm" needs either "schema" or "collection" attribute

And if I use collection="users" with quotes, I get:

Exception from Deps recompute function: Error: users is not in the window scope

Any idea why this happens?

Thanks.

@odesey
Copy link
Author

odesey commented Jun 3, 2014

@afuggini , I initially go the errors you were getting. Make sure that when you declare the Schema that there is no var in front of it. So instead of var Schema = ... do Schema = ...

See if that helps.

@aldeed
Copy link
Collaborator

aldeed commented Jun 3, 2014

@odesey, the fix is actually pretty simple. You're referencing Schema.UserProfile before you define it. So move the Schema.UserProfile definition to above the Schema.User definition, and things will work. I fixed this in the readme code now, and also removed the var so that the snippet should work when copied into an app.

It works with either:

<fieldset>
  {{> afQuickField name='email'}}
  {{> afObjectField name='profile'}}
</fieldset>

Or:

<fieldset>
  {{> afQuickField name='email'}}
  {{> afQuickField name='profile.firstName'}}
  {{> afQuickField name='profile.lastName'}}
  {{> afQuickField name='profile.gender'}}
</fieldset>

Depending on whether you want an automatic field grouper.

@afuggini, see also "Should the value of schema and collection have quotation marks around it?"

@odesey
Copy link
Author

odesey commented Jun 3, 2014

Wow, it works! That was pretty simple.

Thanks for all the help! Really appreciate it!

For the folks who end up here is the future simply make my original Schema look like this:

    Schema = {};

    Schema.UserProfile = new SimpleSchema({
        firstName: {
            type: String,
            regEx: /^[a-zA-Z-]{2,25}$/
        },
        lastName: {
            type: String,
            regEx: /^[a-zA-Z]{2,25}$/
        },
        gender: {
            type: String,
            allowedValues: ['Male', 'Female']
        },
        bio: {
            type: String,
        },
        avatar: {
            type: String,
        },
        pinCode: {
            type: Number,
            min: 7,
            max: 7
        },
        phoneNumber: {
            type: Number,
            min: 9,
            max: 10
        }
    });

    Schema.User = new SimpleSchema({
        _id: {
            type: String,
            regEx: SimpleSchema.RegEx.Id
        },
        email: {
            type: String,
            regEx: SimpleSchema.RegEx.Email
        },
        createdAt: {
            type: Date
        },
        profile: {
            type: Schema.UserProfile,
        },
        services: {
            type: Object,
            optional: true,
            blackbox: false
        }
    });

    Meteor.users.attachSchema(Schema.User);

And then in your template file, this will work:

{{> afObjectField name='profile'}}

Make sure you have the helper from my original post and everything will work!

Thanks again for the help @aldeed !

@aldeed
Copy link
Collaborator

aldeed commented Jun 3, 2014

Glad to hear it.

@aldeed aldeed closed this as completed Jun 3, 2014
@CaptainChainsaw
Copy link

Hi,

I've tried the above steps, I'm getting the form validating but it doesn't appear to be inserting into the Meteor user profile. I'm a complete noob to Meteor so any advice on how to get the values inserted and prepopulated on the form when the user logs in the next time would be great.

I've got the schema, the helper and my template (below).

When I run Meteor.users.find().fetch(); on the console I get _id, emails and services.

My template looks like this:

<template name="signupForm">
    <div class="panel-body">
    {{#autoForm collection=users id="signupForm" doc=editingDoc  type="insert"}}
    <fieldset>
      {{> afObjectField name='profile'}}
    </fieldset>
    <button type="submit" class="btn btn-primary">Insert</button>
    {{/autoForm}}
   </div>
 </template>

Any ideas?

@aldeed
Copy link
Collaborator

aldeed commented Aug 16, 2014

@CaptainChainsaw, I'm not sure why you'd want them to pre-populate for an "insert" form. Usually you only set doc= for an "update" form. But generally your form looks fine, so you'd have to post a reproduction of your code to be able to know what the issue is. You can also try setting SimpleSchema.debug = true.

@CaptainChainsaw
Copy link

Hi,

I'm making progress with this. I added an Accounts.onCreateUser function with the line user.profile = options.profile;

I've created a Meteor method "saveProfile" and that looks like it will work. I'll try getting this to work before trying anything else.

Thank you for your reply. I'll try the update/insert method again a bit later on when I've got further progress made.

@CaptainChainsaw
Copy link

I've just tried the update method again and that's working. The schema wasn't accessible to both the client and server, so got that fixed :)

@netpoe
Copy link

netpoe commented Nov 26, 2014

I'm getting the label names for each field:

{{#autoForm collection="Meteor.users" doc=user id="userEditForm" type="update"}}
    {{> afQuickField name='name'}} // Displays name and input field
{{/autoForm}}

But when it comes to clicking the submit button, nothing happens, no errors, no console.logs and no updates in the Meteor.users collection.

I've attached the schema in my collections/users.js file and I know it works with SimpleSchema because I'm able to insert users on Signup.

The doc attribute holds the user object brought from the iron:route data.

What can I be doing wrong?

Thanks.

@aldeed
Copy link
Collaborator

aldeed commented Nov 26, 2014

Did you call AutoForm.debug() before submitting to get extra debug logging?

@netpoe
Copy link

netpoe commented Nov 26, 2014

Aldeed, thanks for your quick reply.

I've tried with another collection using the following syntax:

    {{#autoForm collection="Orgs" doc=org id="orgEditForm" type="update"}}
    {{> afQuickField name='name'}}
    {{/autoForm}}

The field is rendering and the Orgs collection document is updating as desired.

How can I do the same with Meteor.users collection?
Regarding the AutoForm.debug() method, should I place it in an Template submit event function?

@netpoe
Copy link

netpoe commented Nov 26, 2014

Nevermind, I changed the schema attribute to collection="Meteor.users" and it worked like a charm.

Awesome plugin, thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants