Completed event never fired on a PageControl

I use Fuse 1.2.1 Build 13974.

I’m not able to go to the last added picture in my picture list. The picture list is made with a PageControl.
I try to use <Completed Handler="{onCompleted}" /> in order to be called when an image is added.
=> But I’m never called.

Here is the source file to reproduce my issue:

<App>
		<JavaScript>
			var Observable = require("FuseJS/Observable");
			var activeImage = Observable();
			var indice = Observable(0);
			var srcFiles = [
				{
					imageFile : "https://firebasestorage.googleapis.com/v0/b/spicythings-f17b1.appspot.com/o/images%2F0.jpeg?alt=media&token=76dac56c-906f-4969-92a6-5d630fb876d2",
					imageid : "0"
				},
				{
					imageFile : "http://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg",
					imageid : "1"
				},
				{
					imageFile : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ84hMKGYnLjbYASltpjWRIIumEGrwWPmkDFVkkr4hppCPekUIY",
					imageid : "2"
				}
			];

			var imageFiles = Observable();

			function addImage(){
				if (indice.value<srcFiles.length){
					imageFiles.add(srcFiles[indice.value]);
					activeImage.value = indice.value;
					indice.value++;
				}
			}
			function onCompleted() {
				console.log("onCompleted");
				if (activeImage.value < indice.value){
					imageList.seekToPath(activeImage.value);
				}
			}
			module.exports = {	
				imageFiles : imageFiles,
				addImage : addImage,
				onCompleted : onCompleted
			};

		</JavaScript>
		
	<Panel ux:Class="SingleImage">
		<Text Value="{imageid}"/>
		<Image ux:Name="pictureURL" Url="{imageFile}" Background="#000" StretchMode="UniformToFill" MinHeight="200" MaxHeight="300">
			<AddingAnimation>
				<Change pictureURL.Opacity="0" Duration="0.5" />
			</AddingAnimation>
		</Image>
	</Panel>
	<StackPanel>

		<PageControl  ux:Name="imageList"  > <!--ClipToBounds="true" IsRouterOutlet="false"-->

			<Completed Handler="{onCompleted}" />

			<Each Items="{imageFiles}">								
	       		<SingleImage Name="{imageid}"/>
			</Each>
		</PageControl>
		<Panel Clicked="{addImage}">
			<Text Value="Add Image"/> 
		</Panel>
	</StackPanel>
</App>

Hi,

Here is how I worked around it.
But if someone could tell me why the former version doesn’t work, it could help.
Thank you.

<App>
		<JavaScript>
			var Observable = require("FuseJS/Observable");
			//var activeImage = Observable("");
			var indice = Observable(0);
			var activeImage = Observable(0);
			var imageToReach = Observable(0);
			var gotoImage = Observable(false);

			var srcFiles = [
				{
					imageFile : "https://firebasestorage.googleapis.com/v0/b/spicythings-f17b1.appspot.com/o/images%2F0.jpeg?alt=media&token=76dac56c-906f-4969-92a6-5d630fb876d2",
					imageid : 0
				},
				{
					imageFile : "http://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg",
					imageid : 1
				},
				{
					imageFile : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ84hMKGYnLjbYASltpjWRIIumEGrwWPmkDFVkkr4hppCPekUIY",
					imageid : 2
				},
				{
					imageFile : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSKSw_-WzNLxUzaJOk4Rm8Ey_WeGoZWAGfswLAhnTQSeECeXjh7IKQWO0Rl",
					imageid : 3
				},
				{
					imageFile : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS25kVh-3UXdWtGWPg6pLnPGU-vZsS7NC5YHRfPQTktUUjJ2FK4",
					imageid : 4
				}
			];

			var imageFiles = Observable();

			function addImage(){
				if (indice.value<srcFiles.length){
					imageFiles.add(srcFiles[indice.value]);
					activeImage.value = indice.value;
					indice.value++;
					gotoImage.value = true;
				}
			}

			function setActiveImage(){
				if (gotoImage.value == true){
					console.log("SetActiveImage ");
					imageToReach.value = activeImage.value;
					imageList.gotoPath(imageToReach.value);
					gotoImage.value = false;
				}
			}

	
			module.exports = {	
				imageFiles : imageFiles,
				addImage : addImage,
				activeImage : activeImage,
				setActiveImage : setActiveImage,
				imageToReach : imageToReach,
			};

		</JavaScript>
		
	<Panel ux:Class="SingleImage">
		<Text Value="{imageid}"/>
		<Image ux:Name="pictureURL" Url="{imageFile}" Background="#000" StretchMode="UniformToFill" MinHeight="200" MaxHeight="300">
			<AddingAnimation>
				<Change pictureURL.Opacity="0" Duration="0.5" />
			</AddingAnimation>
		</Image>
	</Panel>
	<StackPanel>
		<Panel Clicked="{addImage}" Height="50">
			<Text Value="Add Image"/> 
		</Panel>
		
		<PageControl  ux:Name="imageList" ClipToBounds="true" IsRouterOutlet="false" > 
			<Each Items="{imageFiles}">								
	       		<SingleImage Name="{imageid}"/>
			</Each>
		</PageControl>

		<WhileTrue Value="{(activeImage!=imageToReach)}">
				<Callback Handler="{setActiveImage}" />
		</WhileTrue>
	</StackPanel>
</App>

I would need to double-check with The People Who Know ™, but my current understanding after having taken a look at the code and reading Completed docs is that dynamically added pages do not reset the PageControl to “busy” and then Completed again.

The workaround you posted is pretty neat though!

If I were you, I’d instead use a data-bound ActiveIndex on the PageControl. And add a meaningful WhileBusy animation on the images so that you see things are loading, not just have the app stall like nothing is happening, and then suddenly navigate to another page once the image arrives.

Uldis wrote:
The workaround you posted is pretty neat though!

Thank you :slight_smile:

Uldis wrote:
If I were you, I’d instead use a data-bound ActiveIndex on the PageControl. And add a meaningful WhileBusy animation on the images so that you see things are loading, not just have the app stall like nothing is happening, and then suddenly navigate to another page once the image arrives.

Do you have an example of this? Thank you !

Well ActiveIndex is just that - the index of the currently active page: see docs

As for WhileBusy, there’s this example.

Uldis wrote:

Well ActiveIndex is just that - the index of the currently active page: see docs

I’ve tried first. But it doesn’t work if the user swipe the PageControl. So I decided to move to the gotoPath that works perfectly.

As for WhileBusy, there’s this example.

Thank you Uldis.

Right, I hadn’t accounted for user interaction. Your solution with gotoPath is perfectly fine though, so no worries.

The other point about showing a meaningful “busy” state to the user (instead of stalling the app as if nothing is happening) still stands.