# Getting joined data for widget scope

**URL:** https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264
**Category:** Development
**Created:** [April 8, 2016, 10:00pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264 "2016-04-08T22:00:01Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 8, 2016, 10:00pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/1 "2016-04-08T22:00:01Z")

</div>

Continuing the discussion from [A tour of how the Widget (Virtual DOM) code in Discourse works](https://meta.discourse.org/t/a-tour-of-how-the-widget-virtual-dom-code-in-discourse-works/40347):

If I want to access something outside the scope of a widget that only has access to the `User` object, how would I do? I am specifically trying to show a `custom_field` beside the user’s name in a post.

I was thinking of doing something like this in `poster-name` widget:

`contents.push(h('span.post-user-location', attrs.custom_fields.location));`

Any advice?

Furthering this though: how can you tell what `attrs` a widget has access to?

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [April 10, 2016, 11:58pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/2 "2016-04-10T23:58:13Z")

</div>

@eviltrout is there a mechanism for plugins to drive extra data into the widget models?

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [April 11, 2016, 5:59pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/3 "2016-04-11T17:59:19Z")

</div>

The `poster-name` widget has access to the entire post as `attrs`. If you want to attach a new widget within it, you can just pass along `attrs` and get access to everything.

Custom fields in particular are quite commonly needed in plugin widgets, so you can just access them like `attrs.userCustomFields.

Remember to make sure you whitelist the custom field if you want it accessible in your plugin:

```ruby
whitelist_staff_user_custom_field('your_field_name')

```

If you want to see how we use it, the [staff notes plugin](https://github.com/discourse/discourse-staff-notes) uses user custom fields and extends widgets.

---

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 28, 2016, 8:11pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/4 "2016-04-28T20:11:56Z")

</div>

In using the staff notes plugin for reference, I have tried to make a custom field available to the `post-name` widget by doing the following:

In `plugin.rb`:

```
after_initialize do
  require_dependency 'user'
  whitelist_staff_user_custom_field("myCustomField")
end

```

In initializer:

```
import { withPluginApi } from 'discourse/lib/plugin-api';

export default {
  name: "alt-topic-initializer",

  initialize: function(container) {

    withPluginApi('0.2', api => {

      api.decorateWidget('poster-name:after', dec => {
        console.log(dec.attrs.userCustomFields);
      });

    });
 });

```

The result of my `console.log` is `undefined`.

I have tried whitelisting the custom field in Discourse site settings as well.

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [April 29, 2016, 3:13pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/5 "2016-04-29T15:13:04Z")

</div>

That should definitely work. Just to confirm, you were viewing the user as a staff user right? That API only makes the custom field visible for staff users.

---

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 29, 2016, 3:54pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/6 "2016-04-29T15:54:50Z")

</div>

I wanted the custom field to show for everyone. So when a user posts, the user custom field is shown by their name.

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [April 29, 2016, 4:37pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/7 "2016-04-29T16:37:32Z")

</div>

Okay but the api you’re using is for adding them for staff users. Have you tried added them to the `public_user_custom_fields` site setting?

---

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 29, 2016, 4:50pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/8 "2016-04-29T16:50:18Z")

</div>

Ya, I have it in the `public_user_custom_fields` site setting as well. Perhaps I am misunderstanding `userCustomFields`. The field in question is created under customization \> user fields and the user can fill it in under their preferences.

In the rails console, `UserCustomField` gives me:

```
#<UserCustomField:0x007fb6a2bed830
  id: 10,
  user_id: -1,
  name: "user_field_2",
  value: "Cold Lake",
  created_at: Thu, 28 Apr 2016 18:03:11 UTC +00:00,
  updated_at: Thu, 28 Apr 2016 18:03:11 UTC +00:00>

```

So maybe I need to add “user\_field\_2” to the site settings rather than the name of the field?

---

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 29, 2016, 4:53pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/9 "2016-04-29T16:53:47Z")

</div>

> [@stevenpslade](#):
>
> So maybe I need to add “user\_field\_2” to the site settings rather than the name of the field?

Bingo! 🎊 That was the issue! So the question is, why is the name of the custom user field like this?

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [April 29, 2016, 4:57pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/10 "2016-04-29T16:57:47Z")

</div>

Custom fields are a database structure originally built for plugins to store meta data associated with various things, including users. Originally the only way to create/update them was via a plugin.

Later we added that custom field admin section to make it easier for discourse admins to add forms and capture certain values. It uses the same back end as the plugin system, but you need to use the database name to access them.

It might be a good idea to accept either name, now that you mention it. I doubt there would be a conflict if we searched by `name` first and if not then `value`.

---

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 29, 2016, 5:02pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/11 "2016-04-29T17:02:27Z")

</div>

![](https://global.discourse-cdn.com/meta/original/3X/e/e/ee8412ffdde6ec4ab0614c24ce8550518f7df9b4.png)

So in the admin section, the **Field Name** isn’t in the database, only the value?

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [April 29, 2016, 5:30pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/12 "2016-04-29T17:30:56Z")

</div>

The `UserField` table corresponds those form fields to `UserCustomField`s.

---

<div class="post-metadata">

### Author: ![stevenpslade](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stevenpslade/32/53550_2.png) [@stevenpslade](https://meta.discourse.org/u/stevenpslade)
#### Post date: [April 29, 2016, 5:58pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/13 "2016-04-29T17:58:43Z")

</div>

Ok, thanks. So for now the best way to access the `UserCustomField` in the widget is to just whitelist the `user_field_X` name in site settings.

Otherwise, in the `plugin.rb` I would need to do something along the lines of, find `UserField` with name “myCustomField”, get the `id` and then whitelist `user_field_<id>` somehow without site settings. Obviously possible but maybe just easier to look up the user field number and do it in site settings.

---

<div class="post-metadata">

### Author: ![Overgrow](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/overgrow/32/478189_2.png) [@Overgrow](https://meta.discourse.org/u/Overgrow)
#### Post date: [July 25, 2016, 10:02am UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/14 "2016-07-25T10:02:02Z")

</div>

I’d like to follow this topic… In mentioned `poster-name` widget you have explained how to access User `custom_fields`.

From the same widget I’d like to access columns in `user_stats` table instead.

I know that any of `user_stats` variables needs to be passed to widget as `attrs` so I’d like to extend underlying functions.

I believe that the data source is `post_serializer.rb` and then also `transform-post.js.es6` creates `attrs` in `transformBasicPost(post)`.

This doesn’t work, I must be missing something… Thx in advance.

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [July 25, 2016, 3:40pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/15 "2016-07-25T15:40:22Z")

</div>

That is correct. You need to add the code to the serializer, then the transformer.

If it’s not working we’ll need a little more information. Is the json returned from the server including what you want?

---

<div class="post-metadata">

### Author: ![Overgrow](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/overgrow/32/478189_2.png) [@Overgrow](https://meta.discourse.org/u/Overgrow)
#### Post date: [July 25, 2016, 4:44pm UTC](https://meta.discourse.org/t/getting-joined-data-for-widget-scope/42264/16 "2016-07-25T16:44:23Z")

</div>

Thanks for confirming my direction… 🙂

I had to re-check everything and found a bug on my part.. This code works for me.. Example is getting `last_seen_at` from `user` object. Would be fine for highlighting online users..

Thanks for this great project!

**post\_serializer.rb**

> ```
> attributes :post_number,
> :user_last_seen_at,
>              
> def user_last_seen_at
> object.try(:user).try(:last_seen_at)
> end
> 
> ```

**transform-post.js.es6**

> ```
> export function transformBasicPost(post) {
> ...
> const postAtts = {
> ... 
> user_last_seen_at: post.user_last_seen_at,
> 
> ```
