With thanks to @Lovor's investigative answer, here's the approach that worked for me.
1. Add meta to REST as JSON:
In the plugin or theme functions, get the meta, maybe_unserialize
it, json_encode
it, and add it to the REST API:
function add_custom_meta_to_rest( $data, $user, $context ) {
// Add some check here to set a default value if the key does not exist.
$usermeta = get_user_meta( $user->ID, 'meta_key', true );
$data->data['meta']['meta_key'] = json_encode( maybe_unserialize( $usermeta ) );
return $data;
}
add_filter( 'rest_prepare_user', 'add_custom_meta_to_rest', 10, 3 );
2. Get the data in your block
In your block JS file, import useSelect
and from there you can get the data inside your edit
function:
// Import `useSelect`.
import { useSelect } from '@wordpress/data';
// Get users.
const users = useSelect(select => select('core').getUsers());
// Get user meta from `users` and parse the JSON.
// Be sure the user ID is set first, in this case as an attribute.
// Also be sure to replace the meta key.
var userMeta = users && users.length > 0 && users.find((user) => user.id === attributes.userId).meta.meta_key;
userMeta = JSON.parse(userMeta);
Test it to be sure: console.log(userMeta)
3. FYI...
If you want, you can also get the current user:
const currentUser = useSelect(select => select('core').getCurrentUser());
And then set userId
as the current user's ID if it isn't set:
// You'll have import `useEffect` for this:
import { useEffect } from '@wordpress/element';
// Set userId to the current user id if it is not set.
useEffect(() => {
if (!attributes.userId) {
setAttributes({ userId: currentUser.id });
}
}, []);
In my case, I needed all users anyway, but you can also get a single value by user ID, as @Lovor described:
const userName = useSelect(select => select('core').getUser(1,{'_fields':'name'}));
console.log(userName);
Note that if the metadata was an associative PHP array it'll be parsed as a Javascript object. If you want, you could convert it to an array of objects to more easily loop through and use the keys as values:
if (userMeta && typeof userMeta === 'object') {
userMeta = Object.keys(userMeta).map((key) => {
return { ...userMeta[key], id: key };
});
}
Hope this helps someone.