Skip to content

Commit

Permalink
proof of concept: support pushEvent returning a promise (#3475)
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 authored Oct 18, 2024
1 parent 1ba8ef5 commit 280d381
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 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));
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))
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
31 changes: 30 additions & 1 deletion assets/test/event_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,35 @@ describe("pushEvent replies", () => {
})
})

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

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

test("pushEvent without connection noops", () => {
let view
let pushedRef = "before"
Expand All @@ -190,7 +219,7 @@ describe("pushEvent replies", () => {
Gateway: {
mounted(){
stubNextChannelReply(view, {transactionID: "1001"})
pushedRef = this.pushEvent("charge", {amount: 123})
pushedRef = this.pushEvent("charge", {amount: 123}, () => {})
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions assets/test/js_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe("JS", () => {
describe("hook.js()", () => {
let js, view, modal
beforeEach(() => {
view = setupView(`<div id="modal">modal</div>`)
view = setupView("<div id=\"modal\">modal</div>")
modal = view.el.querySelector("#modal")
let hook = new ViewHook(view, view.el, {})
js = hook.js()
Expand All @@ -35,7 +35,7 @@ describe("JS", () => {
test("exec", done => {
simulateVisibility(modal)
expect(modal.style.display).toBe("")
js.exec(`[["toggle", {"to": "#modal"}]]`)
js.exec("[[\"toggle\", {\"to\": \"#modal\"}]]")
jest.advanceTimersByTime(100)
expect(modal.style.display).toBe("none")
done()
Expand Down
2 changes: 1 addition & 1 deletion assets/test/view_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ describe("View Hooks", function(){
})
let customEl = document.createElement("custom-el")
el.appendChild(customEl)
let view = simulateJoinedView(el, liveSocket)
simulateJoinedView(el, liveSocket)
})

test("view destroyed", async () => {
Expand Down

0 comments on commit 280d381

Please sign in to comment.