How to observe client-side data changes in Charm without React?

I'm using Charm for state management in my Roblox game and have successfully set up server-client synchronization using the official example from the charm-example repository. The server-side implementation works perfectly with the provided example. However, I'm not using React on the client side and need guidance on the best practices for observing atom changes and updating the UI accordingly. Here's my current client-side code:
print("Hello World");

const syncer = client({ atoms });
remotes.sync.connect((payload: SyncPayload<GlobalAtoms>) => {
syncer.sync(payload);
print(`synced ${payload}`);
});
remotes.init();

// Observe changes to datastore values
subscribe(datastore.players, (newValue: any, oldValue: any) => {
print("Player data has changed:");
print("New value:", newValue);
print("Old value:", oldValue);
});

// Observe data changes for a specific player
const playerId = Players.LocalPlayer.Name;
subscribe(datastore.players, (newValue: PlayerDataMap) => {
const playerData = newValue[playerId];
if (playerData) {
print(`${playerId}'s data:`, playerData);
print(`${playerId}'s money:`, playerData.money);
}
});

// 10 times for loop
for (let i = 0; i < 10; i++) {
print("Hello World");
task.wait(1);
remotes.tap.fire();
}
print("Hello World");

const syncer = client({ atoms });
remotes.sync.connect((payload: SyncPayload<GlobalAtoms>) => {
syncer.sync(payload);
print(`synced ${payload}`);
});
remotes.init();

// Observe changes to datastore values
subscribe(datastore.players, (newValue: any, oldValue: any) => {
print("Player data has changed:");
print("New value:", newValue);
print("Old value:", oldValue);
});

// Observe data changes for a specific player
const playerId = Players.LocalPlayer.Name;
subscribe(datastore.players, (newValue: PlayerDataMap) => {
const playerData = newValue[playerId];
if (playerData) {
print(`${playerId}'s data:`, playerData);
print(`${playerId}'s money:`, playerData.money);
}
});

// 10 times for loop
for (let i = 0; i < 10; i++) {
print("Hello World");
task.wait(1);
remotes.tap.fire();
}
Solution:
Message Not Public
Sign In & Join Server To View
Jump to solution
9 Replies
eisuke
eisukeOP2mo ago
GitHub
GitHub - littensy/charm-example: 🍀 Use Charm to build a Roblox game
🍀 Use Charm to build a Roblox game. Contribute to littensy/charm-example development by creating an account on GitHub.
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
eisuke
eisukeOP2mo ago
React will not be used in this project. In that case, how should I observe the value?
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
eisuke
eisukeOP2mo ago
I don't plan to include any UI libraries. I simply want to observe on the client side. Is the current code okay?
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
eisuke
eisukeOP2mo ago
wo
import Charm = require("@rbxts/charm");

export function useAtom<State>(
callback: () => State,
onChange?: (value: State) => void
): [() => State, (value: State) => void] {
let currentValue = callback();

const getValue = () => currentValue;

const setValue = (value: State) => {
currentValue = value;
if (onChange) {
onChange(value);
}
};

const unsubscribe = Charm.subscribe(callback, (value: State) => {
currentValue = value;
if (onChange) {
onChange(value);
}
});

return [getValue, setValue];
}

export default useAtom;
import Charm = require("@rbxts/charm");

export function useAtom<State>(
callback: () => State,
onChange?: (value: State) => void
): [() => State, (value: State) => void] {
let currentValue = callback();

const getValue = () => currentValue;

const setValue = (value: State) => {
currentValue = value;
if (onChange) {
onChange(value);
}
};

const unsubscribe = Charm.subscribe(callback, (value: State) => {
currentValue = value;
if (onChange) {
onChange(value);
}
});

return [getValue, setValue];
}

export default useAtom;
const [getPlayersData, setPlayersData] = useAtom(datastore.players, (newValue) => {
print("Player data changed:", newValue);

const playerId = Players.LocalPlayer.Name;
const playerData = newValue[playerId];
if (playerData) {
print(`${playerId}'s updated data:`, playerData);
print(`${playerId}'s updated money:`, playerData.money);
}
});
const [getPlayersData, setPlayersData] = useAtom(datastore.players, (newValue) => {
print("Player data changed:", newValue);

const playerId = Players.LocalPlayer.Name;
const playerData = newValue[playerId];
if (playerData) {
print(`${playerId}'s updated data:`, playerData);
print(`${playerId}'s updated money:`, playerData.money);
}
});
I'll go withsubscribe
Tesmi
Tesmi2mo ago
just use built-in library tools such functions as: subscribe, observe etc.
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View

Did you find this page helpful?