I'm writing chrome extension and decided to wrap everything into streams, mostly for training and take a look into rxjs.
So I’m stuck with such a problem. I have two streams, one stream is static (don’t know how to correctly name it) and one dynamic.
A static stream is that one who emits value only when you subscribe to it (getPath$), it return value from a chrome storage. A dynamic (message$) stream is a stream which listening for events(messages).
So my goal is somehow to merge this two stream and every time when I’m receiving a message from message$ get value from a getPath$ and make some calculations based on two values.
type Handler = (
message: any,
sender: any,
sendResponse: (response: any) => void
) => void;
type Values = string | string[];
const getValues = (values: Values) => (cb) => chrome.storage.local.get(values, cb)
const getPathBinded = bindCallback(getValues('path'))
const getPath$ = getPathBinded()
const message$ = fromEventPattern(
(handler: Handler) => chrome.runtime.onMessage.addListener(handler),
(handler: Handler) => chrome.runtime.onMessage.removeListener(handler),
(message, sender, sendResponse) => ({ message, sender, sendResponse })
).pipe(
map(
({ message }) => message
)
)
I found how to do this in such a way:
message$.pipe(
switchMap(
_ => getPath$,
(oV, iV) => {
//doing some calculation
}
)
)
Or
combineLatest(
message$,
getPath$,
).pipe(
map((a, b) => {
//doing some calculation
})
)
Seems like it's working, but it feels like I am doing wrong. Any suggestions or how to do it following best approaches? Also, please correct me in definitions.
UPD Here the full code: https://gist.github.com/ And the latest version which is work
const merged$ = message$.pipe(
switchMap(sendedPath => combineLatest(
path$,
unit$
).pipe(
map(([path, unit]) => [sendedPath, path, unit]))
)
)
chrome.storage.local.get(values, cb)
be recalculated with every new message or it is fine to use the first for all messages? – Oles Savluk