I want my Svelte SPA to interact with some data from a DB. For this, I used Sapper, so I can open the connection to DB in the server.js, and listen to it through its pub/sub mechanism. How can I then parse the message to my reactive store? here, channelArray is just a writable([]) imported from a ‘/.store.js’
With this code, I can parse to the App data to the store, but only when initialized?
// server.js
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '@sapper/server';
import { channelArray, chNum } from './components/store.js';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
polka() // You can also use Express
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.listen(PORT, err => {
if (err) console.log('error', err);
});
const Redis = require('ioredis');
const chpattern = "vac:*";
const sub = new Redis();
sub.psubscribe(chpattern);
sub.on("pmessage", function (pattern, channel, message) {
console.log(`REDIS updated, number of channels`);
chNum.subscribe(value => {console.log(value)});
console.log(`Channel ${channel} Received msg: ${message}`);
var ch = parseInt( channel.slice(4) );
//if (ch >= 0 && ch < chNum ) {
if (ch >= 0 ) {
console.log('REDIS updated');
channelArray[ch].value = message;
channelArray[ch].lastupdate = Date.now();
}
});
And the relevant part of the index.html
<script>
import Ctrlbox from '../components/Ctrlbox.svelte';
import { channelArray, chNum } from '../components/store.js';
import Blinkbox from '../components/blinkbox.svelte'
let ch = 0;
const addChannel = () => {
$channelArray = [...$channelArray, {
id: ch++,
value: 0,
lastupdate: new Date()
}];
};
const box = [0,1,2];
for (var i=0; i< box.length; i++) {
addChannel();
}
chNum.set(ch);
</script>
2
Answers
Seems to me that you directly manipulating the store. I don’t think that is the best approach. According to the docs a
writable
has aset
andupdate
method. You useset
when you want to change the value of the variable and don’t care about the previous value.update
is used if you care about the previous value, so for incrementing for example.It seems that
update
would fit your use case, as you seem to care about the previous state. So I would propose this:While this on the backend
technically works, it does not do what you expect. The imported
channelArray
on the backend is not the same as on the frontend, they’re different instances ofwritable
and there’s no connection or binding between them.You’ll need to add some sort of communication between front- and backend. AJAX requests or socket io, whatever suits best. Some REST API is probably the easiest solution.
I went through this with an electron app, but there I can use the built in IPC so that the frontend and backend can exchange data.