Using Alpine.js
for the first time.
I have a video
tag to show the camera feed, in a modal, which is initialized when the video
tag is initialized using
<div x-data="initTestData()" @data-transfer.window="check=$event.detail.check; runningTest=true;" class="modal fade">
<video
class="w-100 rounded"
id="test-video"
x-init="initTest(check)">
</video>
</div>
which is triggered by
<i @click="$dispatch('data-transfer', {check: check})" data-bs-toggle="modal" role="button"></i>
and the js is defined as
function initTestData() {
console.log('init test data');
return {
check: null,
resource: null,
runningTest: false,
initTest(check) {
console.log('Check initialized: ', check);
const video = document.getElementById('test-video');
navigator.mediaDevices.getUserMedia({
video: {
facingMode: 'user'
}
}).then(stream => {
this.resource = stream;
// Older browsers may not have srcObject
if ("srcObject" in video) {
video.srcObject = stream;
} else {
// Avoid using this in new browsers, as it is going away.
// @ts-ignore
video.src = window.URL.createObjectURL(stream);
}
video.onloadedmetadata = function () {
video.play();
};
});
},
closeTest(check) {
this.runningTest = false;
if (this.resource) {
let tracks = this.resource.getTracks(); // get all tracks from the media stream
tracks.forEach(track => track.stop()); // stop each track
}
}
}
}
But the initTest()
method is called only once. After the modal is closed and opened again, the initTest()
method is not called to reinitialise the camera.
2
Answers
Got it solved by adding blank
x-data
on thevideo
tag.It looks like
$watch
can only be used withx-data
on the same element.x-init is called only once when the Alpine object is intialized.
When you close the modal the object is still there and x-init is no more invoked.
To resolve you can invoke initTest() in the event handler:
and remove
x-init="initTest(check)"
Another option can be adding a $watch over a variable:
And varying the value of the variable when dispatching the event.
For example:
But the event must be dispatched also in the modal "dismiss" to let closeTest() be called