Skip to content

Commit

Permalink
proof of concept: support pushEvent returning a promise
Browse files Browse the repository at this point in the history
This is a breaking change. Until now, pushEvent always returned the ref,
but with this change it returns a promise by default, if no onReply
function is given.

Relates to: #1937
  • Loading branch information
SteffenDE committed Oct 18, 2024
1 parent d31b563 commit ee6c265
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
30 changes: 28 additions & 2 deletions assets/js/phoenix_live_view/view_hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,37 @@ export default class ViewHook {
}
}

pushEvent(event, payload = {}, onReply = function (){ }){
pushEvent(event, payload = {}, onReply){
if (onReply === undefined) {
return new Promise((resolve, reject) => {
try {
const ref = this.__view().pushHookEvent(this.el, null, event, payload, (reply, ref) => resolve({reply, ref}));
if (ref === false) {
reject(new Error("unable to push hook event. LiveView not connected"))
}
} catch (error) {
reject(error)
}
});
}
return this.__view().pushHookEvent(this.el, null, event, payload, onReply)
}

pushEventTo(phxTarget, event, payload = {}, onReply = function (){ }){
pushEventTo(phxTarget, event, payload = {}, onReply){
if (onReply === undefined) {
return new Promise((resolve, reject) => {
try {
this.__view().withinTargets(phxTarget, (view, targetCtx) => {
const ref = view.pushHookEvent(this.el, targetCtx, event, payload, (reply, ref) => resolve({reply, ref}))
if (ref === false) {
reject(new Error("unable to push hook event. LiveView not connected"))
}
})
} catch (error) {
reject(error)
}
});
}
return this.__view().withinTargets(phxTarget, (view, targetCtx) => {
return view.pushHookEvent(this.el, targetCtx, event, payload, onReply)
})
Expand Down
34 changes: 33 additions & 1 deletion assets/test/event_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,38 @@ describe("pushEvent replies", () => {
})
})

test("promise", (done) => {
let view
let pushedRef = null
let liveSocket = new LiveSocket("/live", Socket, {
hooks: {
Gateway: {
mounted(){
stubNextChannelReply(view, {transactionID: "1001"})
this.pushEvent("charge", {amount: 123}).then(({reply, ref}) => {
pushedRef = ref
processedReplies.push({resp: reply, ref})
view.el.dispatchEvent(new CustomEvent("replied", {detail: {resp: reply, ref}}))
})
}
}
}
})
view = simulateView(liveSocket, [], "")
view.update({
s: [`
<div id="gateway" phx-hook="Gateway">
</div>
`]
}, [])

view.el.addEventListener("replied", () => {
expect(pushedRef).toEqual(0)
expect(processedReplies).toEqual([{resp: {transactionID: "1001"}, ref: 0}])
done()
})
})

test("pushEvent without connection noops", () => {
let view
let pushedRef = "before"
Expand All @@ -190,7 +222,7 @@ describe("pushEvent replies", () => {
Gateway: {
mounted(){
stubNextChannelReply(view, {transactionID: "1001"})
pushedRef = this.pushEvent("charge", {amount: 123})
pushedRef = this.pushEvent("charge", {amount: 123}, () => {})
}
}
}
Expand Down

0 comments on commit ee6c265

Please sign in to comment.