I'm having an issue creating a Progress bar that tracks the real time progress of a VueX mutation.
I have a button component that runs a mutation when the user clicks the button. This mutation goes through an array and performs a function on each item in the array. While performing this function it updates a 'progress' status in the store. I have a progress bar component that reads this 'progress' status from the store as a computed property.
I was hoping that as the progress status updates so would the progress bar but it seems I am having an issue with the DOM Rendering the change as quickly as it is being updated. My mutation runs and the progress bar goes from 0 to 100 with no update in-between.
I guess I'm having an issue conceptualizing why my DOM isn't redrawing as quickly as I am updating the 'progress' status and if there is any way of accomplishing this
I've found that the 'For' loop I use to process my array 'freezes' the dom and stops it from re-rendering. To fix this I've used a 'setTimeout' call. This seems like a hack but will hopefully help someone else who comes up against this issue. More answers appreciated. thanks to #Eric Guan for putting me down this path. I found the answer on another post here -> How to stop intense Javascript loop from freezing the browser
var self = this;
var animals = ['dog', 'cat','lion','tiger','bear'];
var processing = function() {
var animal = animals.shift();
console.log(animal);
if (animals.length > 0) {
console.log(animals.length);
var timer = setTimeout(processing, 1000);
self.$store.commit('updateStatus', {progress : animals.length*20, msg: 'Progress Bar Test', status: 'processing', display: true});
} else {
console.log('clearing timeout');
self.$store.commit('updateStatus', {progress : 100, msg: 'Progress Bar Test', status: 'processing', display: false});
clearTimeout(timer);
}
}
processing();
Related
I am using react-native-track-player package to play music files in my React Native mobile application.
There due to some issue, I need to stop the track-player once the queue of audio tracks reaches the end. For that, I use the event PlaybackQueueEnded to invoke the following code snippet. (I have used it in the useTrackPlayerEvents hook along with the PlayerTrackChanged event which when fired, sets the title, author, and background of the current audio file being played).
useTrackPlayerEvents(
// To set the title, author, and background of the current audio file being played
[Event.PlaybackTrackChanged, Event.PlaybackQueueEnded],
async event => {
if (
event.type === Event.PlaybackTrackChanged &&
event.nextTrack !== null
) {
const track = await TrackPlayer.getTrack(event.nextTrack);
const title = track?.title;
const artist = track?.artist;
const artwork: SetStateAction<any> = track?.artwork;
setTrackTitle(title);
setTrackArtist(artist);
setTrackArtwork(artwork);
}
// To stop the player once it reaches the end of the queue
if (
event.type === Event.PlaybackQueueEnded &&
event.position === progress.duration
) {
TrackPlayer.stop();
}
},
);
But the above code doesn't work as I expected. Seems the event PlaybackQueueEnded is not fired when playing the last track of the queue. Can somebody please help me to solve this issue?
Thank you.
PS: I am taking the current time and duration of the audio file being played by using the useProgress hook and have assigned its value to the progress variable. By that, I'm taking progress.position and progress.duration.
PlaybackQueueEnded will be fired when the song is finished and you dont need to check if event.position === progress.duration
I have created a component that allows users to select objects from a list and put them into another "selected list" lets say. So there are 100 items in the main list and however many in the users selected list. They can of course remove and add items as they want.
There are two buttons at the bottom of the modal. Cancel and Update. Where Cancel forgets anything they have added or removed (essentially an Undo of when they popped up the modal) and Update technically does nothing because when you are adding and removing, I am actually updating the real selected list.
So my data has these two properties (among others of course):
originalSelections: [],
selectedMedications: [],
There is a method that only gets called one time to set the selectedMedications property to whatever the current state of originalSelections is. I have a console.log to prove I am not running this method more than once and it NEVER gets hit again.
console.log('Post Initing');
let Selected = [];
for (let med of this.value.OtherNotFromEpic) {
let match = this.otherMedications.find(x => { return x.value === med });
if (match) {
Selected.push(JSON.parse(JSON.stringify(match)));
this.originalSelections.push(JSON.parse(JSON.stringify(match)));
this.selectedMedications.push(JSON.parse(JSON.stringify(match)));
}
}
I was baffled at why the selectedMedications was changing, so I added a watch to let me know if it was:
watch: {
originalSelections(newValue) {
console.log(' ** Original Selection Changed', this.init, newValue);
},
},
The Cancel method is as follows:
cancel() {
$('#' + this.modalID).modal('hide');
console.log('Cancel: this.originalSelections', JSON.parse(JSON.stringify(this.originalSelections)));
this.selectedMedications = this.originalSelections;
this.$nextTick(() => {
console.log(' Cancelled: this.selectedMedications', JSON.parse(JSON.stringify(this.selectedMedications)));
});
},
You can see that I am setting selectedMedications to whatever it was originally.
The odd thing is... This WORKS 100% the first time I bring up the modal. So I pop up the modal, remove an item, cancel the modal and it brings back the item I removed. Perfect!
If I bring the modal up again, remove that same item or any other item, cancel the modal and that item stays removed and the watch is actually hit. I have NO other place in the code where originalMedications = … or originalMedications.push or even originalMedications.slice ever happen. And it is my understand that the JSON.parse(JSON.stringify(match)) code I use to set it is making a new object and not a reference in any way.
Another odd thing I have found is that if I refresh the page, open the modal, cancel out without doing any adding or removing. Then I bring up the modal again and try either add or remove, then cancel the modal, those items do not revert back to the originalMedications state because originalMedications is the same as selectedMedications. Aargh!
So HOW can a property get altered when I never do anything to it after the initial setting of it?
In the cancel method, when below direct assignment is done here after both data is referring to same (since its array). So any time after the first cancel both originalSelections and selectedMedications array would have same reference and hence same data.
this.selectedMedications = this.originalSelections;
instead better to use concat as below? This will create a copy of originalSelections and assign that to selectedMedications. So any operations on selectedMedications will not affect the originalSelections.
this.selectedMedications = [].concat(this.originalSelections);
I have different albums, the contents of which I want to show in lightgallery.
My initial call goes like :
$('.dlCms_c_Carousel').lightGallery({
dynamic : true ,
dynamicEl : dlThis.LGDynEl ,
thumbnail : true ,
mode : 'lg-fade' ,
});
This works perfect, but then, when opening another album, I want the one or the other way to refresh such that the new content of dynamicEl is shown.
Is there a way to do it ?
I was trying a
$('.dlCms_c_Carousel').data("lightGallery").destroy(true)
before, but that messed up. I.e. there seemed to be some functionality, but it looked like the lightbox lost some styling and wasn't opaque any more.
Any hints ?
I'm using Waypoint.js for infinite scrolling with lightgallery.
The solution that I found for dynamic refresh was:
var gallery = $(".infinite-container").lightGallery({
selector: '.item'
});
var infinite = new Waypoint.Infinite({
element: document.querySelector('.infinite-container'),
onAfterPageLoad: () => {
gallery.data('lightGallery').destroy(true);
gallery = $(".infinite-container").lightGallery({
selector: '.item'
});
}
});
From my experience, the object returned from the lightgallery initialization has to be used on the destroy.
Hope it helps.
Using Durandal 2.0.1 (can't update to 2.1.0 yet due to restrictions on project development) and I have an intermittent issue with the error shown in this question title.
All I'm doing is defining a custom dialog box then showing it:
var pleaseWaitModal = new modalBusy();
dialog.show(pleaseWaitModal);
And when my ajax call is finished I do:
dialog.close(pleaseWaitModal);
...and then display another modal with the results of my ajax call.
This all works perfectly IF the ajax call takes half a second to a second. If it's a quicker call then I get Uncaught TypeError: Cannot read property 'host' of undefined in my console window. The box still closes, it's just that I get a panicky project manager asking what the red error is for...
Is this purely because I'm trying to run "dialog.close()" before "dialog.show()" has properly completed in some circumstances?
The sequence of events is basically:
*user instigates action requiring a detailed modal dialog to appear with data in it
*as it takes several seconds to populate on some occasions, an interim modal dialog is shown with "please wait" in it
*once the ajax request is complete, the "pleasewait" modal is closed and the "detail" modal is shown
*so a bit like:
var pleaseWaitModal = new modalBusy();
dialog.show(pleaseWaitModal);
//set up deferred calls for ajax data and call ...
var deferredAjax = callDataFunction(myparams...);
return deferredAjax.then(function(result) {
dialog.close(pleaseWaitModal);
var detailModal = new detailModal();
detailModal.show(result);
});
So I don't think I can achieve this using the promise on the dialog.show(pleaseWaitModal) call, can I?
Are you using the promise that is returned from the dialog.close function to open your new modal? You might try this:
From your initial dialog:
dialog.show(new modal()).then(function(responseData) {
dialog.show(new pleaseWaitModal(responseData));
});
I think the problem you're running into is async timing related, which is why using the deferred works so well.
EDIT: Related to my comment below, you might look at using only one modal, and putting a loading indicator inside of it, like so:
view.html
<div data-bind="visible: isLoading">
<h1>Please wait...</h1>
<i class="icon-spin icon-spinner icon-4x"></i>
</div>
modalViewModel.js
var vm = {
isLoading: ko.observable(true)
};
vm.activate = function() {
makeAjaxCall().then(function(data) {
vm.isLoading(false);
**Do whatever you need for your ajax return**
return true;
});
});
I think that should work for what you need as an alternative.
Worklight busyindicator not working properly.My isssue is i'm using multipage.On page change i call adapter for webservice and call busy indicator so that it show work in progress while fetching.but what happen is page change and indicator show and hide quickly but adpater still in fetching phase and after sometime data called successfully but during these working no busy indicator shows.
var busyIndicator = null;
function wlCommonInit(){
busyIndicator = new WL.BusyIndicator();
}
This is the code i call on page change.
busyIndicatorDemo();
var viewPath = "views/add_fund_transfer.html";
WL.Page.load(viewPath,
{
onComplete: function() {
PayAnyOne_Controller.GetBranches(GetBranchesProcedureName);
busyIndicator.hide();
}
});
function busyIndicatorDemo() {
busyIndicator.show();
setTimeout(15000);
}
its seems like busyindicator doesn't work with adpater when using in multipage.
Please give me the solution or the problem in my code.
Thanks.
It seems like the problem is in the flow of the code. you're running this code basically:
show busy indicator
load page
when page has finished loading: invoke procedure (async call), and hide busyindicator.
So this generates the behavior you've reported - the busyindicator is shown and quickly hidden once the page has finished loading, even though the service is still fetching data (in an async call)
moving the busyindicator.hide to the onSuccess of the invoke procedure should solve the problem (put it also in the onFailure ...)
Hope this helps