# Setting a timestamp attribute on creation, maybe defaultAttrs issue?

**URL:** <https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814>\
**Category:** Uncategorized\
**Created:** [March 4, 2019, 8:20pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814 "2019-03-04T20:20:32Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![edwardbaeg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/edwardbaeg/32/877_2.png) [@edwardbaeg](https://discuss.prosemirror.net/u/edwardbaeg)\
**Post date:** [March 4, 2019, 8:20pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/1 "2019-03-04T20:20:32Z")

</div>

I’m having issues setting a timestamp attribute to nodes. Here’s a short snippet in the plugin `update` method:

```auto
// set timestamp if there was a change and no previous timestamp
if (prevState && prevState.doc.eq(state.doc) && !node.attrs.ts) {
  node.attrs.ts = new Date().toISOString();
}

```

The issue is that the `ts` attribute will be the same for all nodes with `type` of `paragraph`, even when creating a new `paragraph` node. I am not getting this issue with headers of different levels. If I inspect these `paragraph` nodes, I notice that `node.type.defaultAttrs.ts` are all set to the same timestamp. I couldn’t find documentation for this property.

Specifying attributes in the schema doesn’t solve this issue:

```auto
// add ts attribute to schema
schema.nodes.paragraph.attrs = {
  ts: {
    default: null,
  }
}

```

will throw an error: `Uncaught RangeError: No value supplied for attribute ts`

This error goes away if I manually set defaultAttrs:

```auto
schema.nodes.paragraph.defaultAttrs = {
  ts: null,
}

```

but again, the `ts` attribute for all `paragraph` nodes will be set to the same initial timestamp. Any suggestions?

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [March 4, 2019, 8:34pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/2 "2019-03-04T20:34:02Z")

</div>

> [@edwardbaeg](#):
>
> ```
> node.attrs.ts = new Date().toISOString();
> 
> ```

Nodes, and all the objects they contain, including attributes, are supposed to be _immutable_ values, and should thus not be updated.

If you want to change an attribute you’ll have to create a transaction.

---

<div class="post-metadata">

**Author:** ![edwardbaeg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/edwardbaeg/32/877_2.png) [@edwardbaeg](https://discuss.prosemirror.net/u/edwardbaeg)\
**Post date:** [March 4, 2019, 10:11pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/3 "2019-03-04T22:11:46Z")

</div>

Ahhh right, I feel silly. I’ve refactored to:

```auto
view.dispatch(state.tr.setNodeMarkup(pos, null, attrs))

```

and it seems to be working! However, I’m still unclear with the correct way of specifying attributes in the schema. I could have sworn I saw an example that had a pattern that looked like:

```auto
attrs = {
  foo: {
     default: 'bar',
     hasDefault: true
   }
}

```

But I can’t find it again. For now I’ve gotten it to work by manually setting `schema.nodes.paragraph.defaultAttrs`, is this correct?

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [March 5, 2019, 7:09am UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/4 "2019-03-05T07:09:21Z")

</div>

> [@edwardbaeg](#):
>
> I could have sworn I saw an example that had a pattern that looked like:

That looks like the way it was in some pre-1.0 version. Now it’s enough to say `attrs: {foo: {default: "bar"}}` (see the [docs](http://prosemirror.net/docs/ref/#model.AttributeSpec)). Don’t monkey-patch `.defaultAttrs`—that might break in future versions.

---

<div class="post-metadata">

**Author:** ![edwardbaeg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/edwardbaeg/32/877_2.png) [@edwardbaeg](https://discuss.prosemirror.net/u/edwardbaeg)\
**Post date:** [March 5, 2019, 6:41pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/5 "2019-03-05T18:41:25Z")

</div>

> [@marijn](#):
>
> That looks like the way it was in some pre-1.0 version. Now it’s enough to say `attrs: {foo: {default: "bar"}}` (see the [docs](http://prosemirror.net/docs/ref/#model.AttributeSpec)). Don’t monkey-patch `.defaultAttrs` —that might break in future versions.

Hmmm in that case, maybe I’m still doing something wrong. If I do not include the `hasDefault: true` attribute, **OR** if I do not manually add `.defaultAttrs` the app will crash with this error:

 ![image](https://discuss.prosemirror.net/uploads/secondsite/original/1X/624eff4a92d33edf74fd482016f7e6fa12d47546.png)

This is the function that is throwing the error:

```auto
function computeAttrs(attrs, value) {
  var built = Object.create(null);

  for (var name in attrs) {
    var given = value && value[name];

    if (given === undefined) {
      var attr = attrs[name];

      if (attr.hasDefault) {
        given = attr.default;
      } else {
        throw new RangeError("No value supplied for attribute " + name);
      }
    }

    built[name] = given;
  }

  return built;
}

```

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [March 5, 2019, 8:00pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/6 "2019-03-05T20:00:20Z")

</div>

> [@edwardbaeg](#):
>
> If I do not include the `hasDefault: true` attribute, **OR** if I do not manually add `.defaultAttrs` the app will crash with this error:

`hasDefault` is a property on the internal `Attribute` type, which you shouldn’t even be touching from user code, so yes, it does look like you’re doing something wrong. How are you creating the `Schema` object?

---

<div class="post-metadata">

**Author:** ![edwardbaeg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/edwardbaeg/32/877_2.png) [@edwardbaeg](https://discuss.prosemirror.net/u/edwardbaeg)\
**Post date:** [March 5, 2019, 8:28pm UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/7 "2019-03-05T20:28:03Z")

</div>

```auto
import { schema } from 'prosemirror-markdown';

// TODO: create our own schema
schema.nodes.paragraph.attrs = {
  ...schema.nodes.paragraph.attrs,
  ts: {
    default: null,
    // temporary hack
    hasDefault: true
  },
};

schema.nodes.heading.attrs = {
  ...schema.nodes.heading.attrs,
  ts: {
    default: null,
    hasDefault: true
  }
};

```

---

<div class="post-metadata">

**Author:** ![edwardbaeg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/edwardbaeg/32/877_2.png) [@edwardbaeg](https://discuss.prosemirror.net/u/edwardbaeg)\
**Post date:** [March 6, 2019, 2:41am UTC](https://discuss.prosemirror.net/t/setting-a-timestamp-attribute-on-creation-maybe-defaultattrs-issue/1814/8 "2019-03-06T02:41:50Z")

</div>

So… I realized that was the hacky way and I have refactored to:

```auto
const extendedSchema = new Schema({
  nodes: schema.spec.nodes
    .update('paragraph', {
      ...schema.spec.nodes.get('paragraph'),
      attrs: {
        ts: {
          default: null,
        }
      },
    }).update('heading', {
      ...schema.spec.nodes.get('heading'),
      attrs: {
        ...schema.spec.nodes.get('heading').attrs,
        ts: {
          default: null,
        }
      }
    }),
  marks: schema.spec.marks,
});

```

which broke a bunch of stuff but I realized the issues were from using `defaultMarkdownParser`. I’m currently building my own markdown parser and it seems like I’m on the right path. Thanks!!
