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

Template specific config is "leaking" into other configurations #3763

Closed
paultannenbaum opened this issue May 15, 2020 · 3 comments
Closed

Comments

@paultannenbaum
Copy link

paultannenbaum commented May 15, 2020

Describe the bug
I have a project that has several reusable widgets. One of them is a header_type that is a select widget, and several different templates use this widget. I have a new template that clones that object type, and changes its default(It does not mutate the original object). However when I do this, all other configurations are now picking up the cloned object settings.

To Reproduce

headerWidget.js

export default {
  label: 'Header',
  name: 'header',
  widget: 'object',
  fields: [
    {
      label: 'Type',
      name: 'type',
      widget: 'select',
      options: Object.values(HEADER_TYPES),
      default: HEADER_TYPES.DEFAULT,
    },
    {
      label: 'Visible',
      name: 'isVisible',
      widget: 'boolean',
      default: true,
    },
  ],
}

// Several templates import and use this config as is, like so:
import * as widgets from './widgets'

const config = {
    widget.header,
    .... other config options
}

// An individual template might try and update a default by doing so:
import * as widgets from './widgets'
import { HEADER_TYPES } from './constants'

const headerWithUpdatedDefaults = () => {
  const header = { ...widgets.header }

  header.fields.find(f => f.name === 'type').default = HEADER_TYPES.LOGO_ONLY

  return header
}

const config = {
    headerWithUpdatedDefaults(),
    .... other config options
}

When implementing via the psuedo code above, all templates now have HEADER_TYPES.LOGO_ONLY set as the default for the select.

Expected behavior
I would expect only the individual template with the updated config to have the default set as HEADER_TYPES.LOGO_ONLY, while all other templates should use the original config of HEADER_TYPES.DEFAULT

Applicable Versions:

  • Netlify CMS version: 2.12.3
  • Git provider: GitHub
  • OS: Mac OS Mojave (10.14)

CMS configuration

config: {
    backend: {
      name: 'git-gateway',
      repo: ***private***,
      branch: process.env.GATSBY_CMS_BRANCH,
    },
    local_backend: isLocalEnv,
    load_config_file: false,
    media_folder: 'static/img',
    public_folder: '/img',
    collections: templates,
  }

** Context **
Using netlify CMS in conjunction with Gatsby
@barthc
Copy link
Contributor

barthc commented May 15, 2020

header.fields.find(f => f.name === 'type').default = HEADER_TYPES.LOGO_ONLY

You are modifying the objects in place here. Why don't you use map and return new objects.

 const newFields =  fields.map((f) => ({
  ...f,
  ...(f.name === 'type' && { default: HEADER_TYPES.LOGO_ONLY }),
}));

return newFields;

@paultannenbaum
Copy link
Author

@barthc I will try this right now and report back, but if you look at the line just above the one you posted, you will see I am cloning the object (const header = { ...widgets.header }). So I still dont understand how I could be modifying the original objects.

@paultannenbaum
Copy link
Author

@barthc So I tried your method and was still getting the same results, but I do think this may actually be a bug on my end and not netlify cms. I did not realize that object destructuring did a shallow clone and not a deep clone, and I think ultimately that is the problem. I am going to close this issue as that seems to be the case as to what was happening.

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

2 participants