Amin Shazrin
Amin Shazrin

Reputation: 83

apostrophecms beforeSave won't work

This is my schema and construct method for automatically update title. But it won’t work at all ! It kept prompt me to fill in Full Name . You may fork my github to see the whole code My Github Apostrophe Tutorial . Someone pleaseeee help me. I falled in love with apostrophe badly. The tutorial that I have been followed is Setting the Title Automatically

module.exports = {
    extend: 'apostrophe-pieces',
    permissionsFields : true,
    name: 'person',
    label: 'Person',
    pluralLabel: 'People',
    beforeConstruct : function(self,options){
        options.addFields= 
        [
            {
                name: 'title',
                label: 'Full Name',
                type: 'string',
                required: true
            },
            {
                name: 'firstName',
                label: 'First Name',
                type: 'string',
                required: true
            },
            {
                name: 'lastName',
                label: 'Last Name',
                type: 'string',
                required: true
            },
            {
                name: 'body',
                label: 'Biography',
                type: 'area',
                options: {
                    widgets: {
                        'apostrophe-rich-text': {
                            toolbar: ['Bold', 'Italic', 'Link', 'Unlink']
                        },
                        'apostrophe-images': {}
                    }
                }
            },
            {
                name: 'phone',
                label: 'Phone',
                type: 'string'
            },
            {
                name: 'thumbnail',
                label: 'Thumbnail',
                type: 'singleton',
                widgetType: 'apostrophe-images',
                options: {
                    limit: 1,
                    minSize: [200, 200],
                    aspectRatio: [1, 1]
                }
            }
        ].concat(options.addFields || [])
    },
    arrangeFields: [{
            name: 'contact',
            label: 'Contact',
            fields: ['firstName', 'lastName', 'phone']
        },
        {
            name: 'admin',
            label: 'Administrative',
            fields: ['slug', 'published', 'tags']
        },
        {
            name: 'content',
            label: 'Biographical',
            fields: ['thumbnail', 'body']
        }
    ],
    construct: function(self, options) {
        self.beforeSave = function(req, piece, options, callback) {
            piece.title = piece.firstName + ' ' + piece.lastName;
            return callback();
        };
    }
};

Upvotes: 1

Views: 314

Answers (2)

Amin Shazrin
Amin Shazrin

Reputation: 83

Thank you Stuart Romanek , Now I know that the required field will prompt user to fill in. I can override it by using contextual just like you said. The problem is , the slug. But I figured that I have to put contextual too.

module.exports = {
    extend: 'apostrophe-pieces',
    permissionsFields : true,
    name: 'person',
    label: 'Person',
    pluralLabel: 'People',
    beforeConstruct : function(self,options){
        options.addFields= 
        [
            {
                name: 'firstName',
                label: 'First Name',
                type: 'string',
                required: true,
            },
            {
                name: 'lastName',
                label: 'Last Name',
                type: 'string',
                required: true
            },
            {
                name: 'title',
                label: 'Full Name',
                type: 'string',
                required: true,
                contextual : true
            },
            {
                name: 'slug',
                label: 'Slug',
                type: 'string',
                required: true,
                contextual: true
            },
            {
                name: 'body',
                label: 'Biography',
                type: 'area',
                options: {
                    widgets: {
                        'apostrophe-rich-text': {
                            toolbar: ['Bold', 'Italic', 'Link', 'Unlink']
                        },
                        'apostrophe-images': {}
                    }
                }
            },
            {
                name: 'phone',
                label: 'Phone',
                type: 'string'
            },
            {
                name: 'thumbnail',
                label: 'Thumbnail',
                type: 'singleton',
                widgetType: 'apostrophe-images',
                options: {
                    limit: 1,
                    minSize: [200, 200],
                    aspectRatio: [1, 1]
                }
            }
        ].concat(options.addFields || [])
    },
    arrangeFields: [{
            name: 'contact',
            label: 'Contact',
            fields: ['firstName', 'lastName', 'phone']
        },
        {
            name: 'admin',
            label: 'Administrative',
            fields: ['slug', 'published', 'tags']
        },
        {
            name: 'content',
            label: 'Biographical',
            fields: ['thumbnail', 'body']
        }
    ],
    construct: function(self, options) {
        self.beforeSave = function(req, piece, options, callback) {
            // Override title and MUST SET CONTEXTUAL to able to save. Let the 
            // backend self.beforeSave method do this thing.
            // You know why I don't set piece.slug ?
            // Because once you already set title , apostrophe made it for you :)
            // BUT must put contextual : true on slug. If not, it will prompt you :*
            piece.title = piece.firstName + ' ' + piece.lastName;
            return callback();
        }
    }
};

Upvotes: 2

Stuart Romanek
Stuart Romanek

Reputation: 2157

beforeSave is going to happen on the server after the user submits the piece, so the browser-side required validation is going to stop the submission before it gets a chance to construct the title property.

You can omit the required property on the title field and your beforeSave will work as expected. If you want to force the title be set programmatically and not include the field in the form, you can set contextual: true on the title field and the field won't be rendered in the manager.

Upvotes: 2

Related Questions