Don't store references into shared objects.

Don't create variables for properties of shared objects. For example, imagine you have a shared object name shared with data that looks like this:

shared = {
	animals: ["aardvark", "bear", "cat"], 
	fruits: ["apple", "banana", "cherry"]
};

And imagine you did this:

var shared;
var animals_shortcut;
function preload() {
	partyConnect(...connection arguments...);
  shared = partyLoadShared("shared");
}

function setup() {
	animals_shortcut = shared.animals
}

function draw() {
 console.log(animals_shortcut);
}

The variable animals_shortcut will point to the the list correctly when you first assign it, but if animals is removed from shared later animals_shortcut will be holding on to data that is no longer shared which will likely lead to confusion and bugs. Accessing shared data via the shared object every time is a better practice.

var shared;

function preload() {
	partyConnect(...connection arguments...);
  shared = partyLoadShared("shared");
}

function setup() {

}

function draw() {
 console.log(shared.animals);
}

Initializing Shared Objects

It is common that you might want to initialize or reset a shared object when the first client connects to an empty room. You can use partyIsHost() in setup() to see if the current client is the first client to join the room. You can then use partySetShared() to initialize all the properties of the shared object at once. This will also remove any existing properties you no longer need. This is a useful pattern and is used in many of the examples.

function setup(){
	if (partyIsHost()) {
		partySetShared(shared, {
			x: 100
		});
	}
}

Checking before initializing values

Sometimes you’ll want to check if a property on a shared object already exists before setting it yourself. A handy way to do this is to use the “Logical nullish assignment operator”. This is relatively new JavaScript operator very well suited to this use.

shared.x ??= 100;

The code above will set shared.x to 100 if shared.x doesn’t exist or if it does exist and is equal to undefined or null. This syntax is clear and concise, but it isn’t in wide use yet as it has only been widely supported since 2020.

There are some other approaches you could consider. Each works a little differently:

// using `hasOwnProperty`
// creates and intializes shared.x if shared.x doesn't exist
// DOES NOT assign 100 to shared.x if shared.x exists and is equal to undefined
if (!shared.hasOwnProperty('x')) {
	shared.x = 100;
}

// using `=== undefined`
// creates and intializes shared.x if shared.x doesn't exist
// DOES assign 100 to shared.x if if shared.x exists and is equal to undefined
// DOES NOT assign 100 to shared.x if if shared.x exists and is equal to null

if (shared.x === undefined) {
	shared.x = 100;
}

// using `in`
// should almost always work, but might not do what you want for property names that exist on Objects like 'constructor', 'toString' (which you should avoid anyway)
if (!('x' in shared)) {
	shared.x = 100
}

// using `!`
// kind of works, but will set x to 100 if x exists but is 0 or false.
if (!shared.x) shared.x = 100;

// using `||=`
// kind of works, but will set x to 100 if x exists but is 0 or false.
shared.x ||= 100;

Logging Shared Objects

p5.party shared objects are proxies so the output from console.log() isn’t exactly the same as logging a normal object. That said, a simple console.log(shared) is often good enough and you can drill down to the [[Target]] in the console to see the full data.