Force page redraw

I have Page 1 where I load data from a JSON source. This works great.

I have a click handler, where if clicked, i’d like to populate page 2 from the data from the JSON source loaded previously.

Basically the page 1 click provides the ID of the child notes to be loaded and drawn in to page 2.

However, even though it’s mapped to a function, it’s not actually drawing anything on page2, it’s coming up empty.

This is the javascript:

        var Observable = require("FuseJS/Observable");


        var data = Observable();
        var mata;

        fetch('https://my.json.soource.com')
            .then(function(response) { return response.json(); })
            .then(function(responseObject) { 
            	mata = responseObject;
            	data.value = responseObject; 

            });

		var locobj = [];

		var foo = function(e){

			var clickedID = e.data.ID;

			mata.ChildNode.forEach(function(Location){
					locobj.push(Location);
				}
			})

		}

		//console.log(JSON.stringify(locobj))
        
        module.exports = {
            data: data,
            foo: foo,
            locations:locobj
        };            

Using the monitor I can see that when I click Page 1, i get actual location objects, so the loading part works.

Code for Page 1:

<Page ux:Name="page1">	
    <ScrollView>
        <Grid ColumnCount="1">
            <Each Items="{data.ParentNode}">
                <DockPanel Height="300" Margin="10,20">
                    <Rectangle Layer="Background" CornerRadius="10" Fill="#fff"  />
                    <Rectangle Height="200" Dock="Top" Margin="0,-10">
                    	<Image File="{Thumb}" Height="230" Padding="30" /> 
                	</Rectangle>
                	<Clicked Handler="{foo}">
                	</Clicked>
                        
                        <Panel>
                        <Text Value="{Title}" TextAlignment="Left" Alignment="Left"  Margin="10,0" Padding="10" Dock="Top" FontSize="22" />
                        <Text Value="{Description}" TextAlignment="Left" Alignment="Left"  Margin="10,30" Padding="10" Dock="Top" TextWrapping="Wrap" />
                        <Text Value="{Thumb.length}" TextAlignment="Left" Alignment="Left"  Margin="10,-10" Padding="10" Dock="Top" TextWrapping="Wrap" />
                    </Panel>
                </DockPanel>
				<Clicked>
					<Set nav.Active="page2" />
				</Clicked>

            </Each>
        </Grid>
    </ScrollView>

	<WhileActive Threshold="0.5">
		<Set shrinkIndicatorWidth.Value="false" />
		<Set indicatorColorAttractor.Value="color0" />
		<Set bgColorAttractor.Value="color0" />
		<Set titleTextAttractor.Value="color0" />
	</WhileActive>
	<ActivatingAnimation>
		<Change h1.Opacity="1" />
		<Change col1.Width="2" />
		<Change c1.Color="White" />
	</ActivatingAnimation>
</Page>

Page 2 is very much the same, except it uses the location object:

		<Page ux:Name="page2">

	        <ScrollView>
	            <Grid ColumnCount="1">

	                <Each Items="{locations}">
	                    <DockPanel Height="300" Margin="10,20">
	                        <Rectangle Layer="Background" CornerRadius="10" Fill="#fff"  />
	                        <Rectangle Height="200" Dock="Top" Margin="0,-10">
	                        	<Image File="Assets/{Thumb}" Height="230" Padding="30" /> 
	                    	</Rectangle>
	                            
	                            <Panel>
	                            <Text Value="{Title}" TextAlignment="Left" Alignment="Left"  Margin="10,0" Padding="10" Dock="Top" FontSize="22" />
	                            <Text Value="{Description}" TextAlignment="Left" Alignment="Left"  Margin="10,30" Padding="10" Dock="Top" TextWrapping="Wrap" />
	                        </Panel>
	                    </DockPanel>

	                </Each>
	            </Grid>
	        </ScrollView>				

		</Page>
So why is page 2 coming up empty if there's location objects being returned as part of the click?

I'm presuming the initial draw has no location object, so nothing is drawn.

Then when I click, I need to force a redraw, which I dont know how to do?

Hi!

Replace your locobj with an Observable insetad of an array, and you should be fine.

In general, I recommend reading the tutorial and documentation on Observable. Observables are the key to how you update the UI from JS. The UI won’t notice if you change a regular array.

Lassen,

It’s just not working.

I’m using the dynamic tab example. As soon as I add an “each” cycle in page 2 it breaks it, and nothing is displayed.

Here’s the entire code, so you can test it for your self:

<App>
	<ClientPanel>
		<Grid Columns="auto,1*,auto" Height="50" Dock="Top" Margin="5">
			<Grid ColumnCount="2" RowCount="2" Width="22" Height="22" Margin="10">
				<Each Count="4">
					<Circle Color="color4" Margin="1.5"/>
				</Each>
			</Grid>
			<Text ux:Name="titleText" Value="Test 2" Color="color0" FontSize="25" Alignment="Center">
				<Font File="Assets/Fonts/Roboto-Black.ttf" />
			</Text>
			<Image File="Assets/search.png" Color="color4" Width="30" Height="30" Margin="10"/>
		</Grid>

		<Panel Dock="Top" Height="60" >
			<Rectangle ux:Name="indicator" CornerRadius="30" Color="color0" LayoutMaster="p1" Margin="0,10" Width="100%" ZOffset="0.1"/>
			<Grid ColumnCount="5" Margin="-30,0">
				<Panel ux:Name="p1" Column="0" ColumnSpan="2"/>
				<Panel ux:Name="p4" Column="3" ColumnSpan="2"/>
			</Grid>

			<Grid ZOffset="1" Margin="-20,0">
				<Column ux:Name="col1" Width="1" WidthMetric="Proportion"/>
				<Column ux:Name="col2" Width="1" WidthMetric="Proportion"/>
				<Column ux:Name="col3" Width="1" WidthMetric="Proportion"/>
				<Column ux:Name="col4" Width="1" WidthMetric="Proportion"/>

				<Text ux:Class="TabHeader" Color="White" Alignment="CenterLeft" Opacity="0" Margin="20,0,0,0" MinWidth="100"/>
				<Image ux:Class="TabIcon" Width="25" Height="25" />

				<Panel HitTestMode="LocalBounds">
					<Grid Columns="auto,1*" Margin="40,0" Alignment="Left">
						<TabIcon ux:Name="c1" File="Assets/basket.png" Color="color0"/>
						<TabHeader ux:Name="h1" Value="Albums" />
					</Grid>
					<Clicked>
						<Set nav.Active="page1" />
					</Clicked>
				</Panel>
				<Panel HitTestMode="LocalBounds">
					<Grid Columns="auto,1*" Margin="30,0" Alignment="Left">
						<TabIcon ux:Name="c2" File="Assets/accountbalance.png" Color="color1"/>
						<TabHeader ux:Name="h2" Value="Artists"/>
					</Grid>
					<Clicked>
						<Set nav.Active="page2" />
					</Clicked>
				</Panel>
				<Panel HitTestMode="LocalBounds">
					<Grid Columns="auto,1*" Margin="30,0" Alignment="Left">
						<TabIcon ux:Name="c3" File="Assets/play.png" Color="color2"/>
						<TabHeader ux:Name="h3" Value="Information"/>

					</Grid>
					<Clicked>
						<Set nav.Active="page3" />
					</Clicked>
				</Panel>
				<Panel HitTestMode="LocalBounds">
					<Grid Columns="auto,1*" Margin="30,0" Alignment="Left">
						<TabIcon ux:Name="c4" File="Assets/person.png" Color="color3" />
						<TabHeader ux:Name="h4" Value="Friends"/>
					</Grid>
					<Clicked>
						<Set nav.Active="page4" />
					</Clicked>
				</Panel>
			</Grid>
		</Panel>
		<PageControl ux:Name="nav">
			<NavigationMotion GotoEasing="BackOut" />
			<Attractor ux:Name="indicatorColorAttractor" Target="indicator.Color" Value="color0" />
			<Rectangle ux:Name="bgColor" Layer="Background" Color="color0" Opacity="0.12"/>
			<Attractor ux:Name="bgColorAttractor" Target="bgColor.Color" Value="color0" />
			<Attractor ux:Name="titleTextAttractor" Target="titleText.Color" Value="color0" />

			<WhileTrue ux:Name="shrinkIndicatorWidth">
				<Change indicator.Width="90" Duration="0.25"/>
			</WhileTrue>

			<Image ux:Class="PagePlaceholder" Margin="8,10,8,0" StretchMode="UniformToFill" ContentAlignment="Top"/>

			<Page ux:Name="page1">
				
		        <ScrollView>
		            <Grid ColumnCount="1">
		                <JavaScript>
		                    var Observable = require("FuseJS/Observable");
							var FileSystem = require("FuseJS/FileSystem");

		                    var data = Observable();
		                    var locations = Observable();

		                    var mata;

		                    fetch('https://dbat-cebd7.firebaseio.com/.json')
		                        .then(function(response) { return response.json(); })
		                        .then(function(responseObject) { 
		                        	mata = responseObject;
		                        	data.value = responseObject; 
		                        	data = data.value.Albums;

		                        });

							

							var foo = function(e){
								mata.Artists.forEach(function(Location){
									locations.add(Location);
								})

								console.log(JSON.stringify(locations))

							}
		                    
		                    module.exports = {
		                        data: data,
		                        foo: foo,
		                        locations:locations
		                    };

		                </JavaScript>
	                    <Each Items="{data.Albums}">
		                    <DockPanel Height="300" Margin="10,20">
		                        <Rectangle Layer="Background" CornerRadius="10" Fill="#fff"  />
		                        <Rectangle Height="200" Dock="Top" Margin="0,-10">
		                        	<Image File="{Thumb}" Height="230" Padding="30" /> 
		                    	</Rectangle>
		                    	<Clicked Handler="{foo}">
		                    	</Clicked>
		                            
		                            <Panel>
		                            <Text Value="{Title}" TextAlignment="Left" Alignment="Left"  Margin="10,0" Padding="10" Dock="Top" FontSize="22" />
		                            <Text Value="{Description}" TextAlignment="Left" Alignment="Left"  Margin="10,30" Padding="10" Dock="Top" TextWrapping="Wrap" />
		                        </Panel>
		                    </DockPanel>
							<Clicked>
								<Set nav.Active="page2" />
							</Clicked>
						</Each>

		            </Grid>
		        </ScrollView>


				<WhileActive Threshold="0.5">
					<Set shrinkIndicatorWidth.Value="false" />
					<Set indicatorColorAttractor.Value="color0" />
					<Set bgColorAttractor.Value="color0" />
					<Set titleTextAttractor.Value="color0" />
				</WhileActive>
				<ActivatingAnimation>
					<Change h1.Opacity="1" />
					<Change col1.Width="2" />
					<Change c1.Color="White" />
				</ActivatingAnimation>
			</Page>
			<Page ux:Name="page2">

		        <ScrollView>
		            <Grid ColumnCount="1">
		            	<Each Items="{locations}">
		                    <DockPanel Height="300" Margin="10,20">
		                        <Rectangle Layer="Background" CornerRadius="10" Fill="#fff"  />
		                        <Rectangle Height="200" Dock="Top" Margin="0,-10">
		                        	<Image File="Assets/screen2.png" Height="230" Padding="30" /> 
		                    	</Rectangle>
		                            
		                            <Panel>
		                            <Text Value="This is a test" TextAlignment="Left" Alignment="Left"  Margin="10,0" Padding="10" Dock="Top" FontSize="22" />
		                            <Text Value="Lorem ipsum bla bla" TextAlignment="Left" Alignment="Left"  Margin="10,30" Padding="10" Dock="Top" TextWrapping="Wrap" />
		                        </Panel>
		                    </DockPanel>
		                </Each>
		            </Grid>
		        </ScrollView>				

				<WhileActive Threshold="0.5">
					<Set shrinkIndicatorWidth.Value="true" />
					<Set indicatorColorAttractor.Value="color1" />
					<Set bgColorAttractor.Value="color1" />
					<Set titleTextAttractor.Value="color1" />
				</WhileActive>
				<ActivatingAnimation>
					<Change h2.Opacity="1" />
					<Change col2.Width="2" />
					<Change c2.Color="White" />
				</ActivatingAnimation>
			</Page>
			<Page ux:Name="page3">
				<PagePlaceholder File="Assets/screen3.png" />
				<WhileActive Threshold="0.5">
					<Set shrinkIndicatorWidth.Value="true" />
					<Set indicatorColorAttractor.Value="color2" />
					<Set bgColorAttractor.Value="color2" />
					<Set titleTextAttractor.Value="color2" />
				</WhileActive>
				<ActivatingAnimation>
					<Change h3.Opacity="1" />
					<Change col3.Width="2" />
					<Change c3.Color="White" />
				</ActivatingAnimation>
			</Page>
			<Page ux:Name="page4">
				<PagePlaceholder File="Assets/screen4.png" />
				<WhileActive Threshold="0.5">
					<Set shrinkIndicatorWidth.Value="false" />
					<Set indicatorColorAttractor.Value="color3" />
					<Set bgColorAttractor.Value="color3" />
					<Set titleTextAttractor.Value="color3" />
				</WhileActive>
				<ActivatingAnimation Scale="0.333">
					<Move Target="indicator" X="1" RelativeTo="PositionOffset" RelativeNode="p4"/>
				</ActivatingAnimation>
				<ActivatingAnimation>
					<Change h4.Opacity="1" />
					<Change col4.Width="2" />
					<Change c4.Color="White" />
				</ActivatingAnimation>
			</Page>
		</PageControl>
	</ClientPanel>
</App>

After a lot of messing about, I found that it’s the way it parses the JSON. Since it’s an array received back, it wraps it in another array, so you get something like [[{}]] instead of [{}].
So I changed it when receiving the response object, I do a .forEach loop, and then add the object in the observable with observable.add(object).

That way, it’s no longer an object wrapped in a double array, but an object in an array.