Strange behavior on Observable under android

function updateValueCrypto(data){
.....
if(data.Currency == "BTC"){
valueSlider.value = valueSlider.value + 1;  <-- I also tried '++' notation instead of '+ 1'
...
//Parse the response
response.json().then(function(data2){<--from here I'm going into calling an API
...
valueSlider.value = valueSlider.value++;
console.log("valueSlider.value: " + valueSlider.value + " and totalCrypto.value: " + totalCrypto.value);

Log (from Android device through the ‘Preview on Android’):

[D6653]: valueSlider.value: 1.999 and totalCrypto.value: 19 <-- why?
[D6653]: valueSlider.value: 2.999 and totalCrypto.value: 19
[D6653]: valueSlider.value: 3.999 and totalCrypto.value: 19
[D6653]: valueSlider.value: 4.9990000000000006 and totalCrypto.value: 19
[D6653]: valueSlider.value: 5.9990000000000006 and totalCrypto.value: 19
[D6653]: valueSlider.value: 6.9990000000000006 and totalCrypto.value: 19
[D6653]: valueSlider.value: 7.9990000000000006 and totalCrypto.value: 19
[D6653]: valueSlider.value: 8.999 and totalCrypto.value: 19
[D6653]: valueSlider.value: 9.999 and totalCrypto.value: 19
[D6653]: valueSlider.value: 10.999 and totalCrypto.value: 19
[D6653]: valueSlider.value: 11.999 and totalCrypto.value: 19
[D6653]: valueSlider.value: 2.995 and totalCrypto.value: 19
[D6653]: valueSlider.value: 12.989 and totalCrypto.value: 19
[D6653]: valueSlider.value: 13.989 and totalCrypto.value: 19
[D6653]: valueSlider.value: 14.984 and totalCrypto.value: 19
[D6653]: valueSlider.value: 15.984 and totalCrypto.value: 19
[D6653]: valueSlider.value: 16.984 and totalCrypto.value: 19
[D6653]: valueSlider.value: 17.984 and totalCrypto.value: 19

Log (as per simulator):

[Viewport]: valueSlider.value: 2 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 3 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 4 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 5 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 6 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 7 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 8 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 9 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 10 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 11 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 12 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 13 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 14 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 15 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 16 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 17 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 18 and totalCrypto.value: 19
[Viewport]: valueSlider.value: 19 and totalCrypto.value: 19

Expected:
The value on Android should increment by “1” (one) and not that “random” value

Funny because from time to time, the value is kind of reset for no reason:

[D6653]: Currency: edg valueSlider.value: 1.999 and totalCrypto.value: 19
[D6653]: Currency: ardr valueSlider.value: 2.999 and totalCrypto.value: 19
[D6653]: Currency: btg valueSlider.value: 3.999 and totalCrypto.value: 19
[D6653]: Currency: cvc valueSlider.value: 4.9990000000000006 and totalCrypto.value: 19
[D6653]: Currency: bat valueSlider.value: 5.9990000000000006 and totalCrypto.value: 19
[D6653]: Currency: etc valueSlider.value: 6.9990000000000006 and totalCrypto.value: 19
[D6653]: Currency: eth valueSlider.value: 2.995 and totalCrypto.value: 19 <--Why?
[D6653]: Currency: neo valueSlider.value: 7.992 and totalCrypto.value: 19
[D6653]: Currency: lbc valueSlider.value: 8.992 and totalCrypto.value: 19
[D6653]: Currency: lmc valueSlider.value: 9.992 and totalCrypto.value: 19
[D6653]: Currency: xel valueSlider.value: 10.992 and totalCrypto.value: 19
[D6653]: Currency: strat valueSlider.value: 11.992 and totalCrypto.value: 19
[D6653]: Currency: xvg valueSlider.value: 12.992 and totalCrypto.value: 19
[D6653]: Currency: exp valueSlider.value: 13.992 and totalCrypto.value: 19
[D6653]: Currency: trst valueSlider.value: 8.98 and totalCrypto.value: 19
[D6653]: Currency: ubq valueSlider.value: 9.98 and totalCrypto.value: 19
[D6653]: Currency: vtc valueSlider.value: 10.98 and totalCrypto.value: 19
[D6653]: Currency: zec valueSlider.value: 14.984 and totalCrypto.value: 19

And yes, I looked at my code and there are only two places where I increase the value of my observable (never reset except at the very first where I set value to ‘0’ - number, not String - it or never decrease the value, only increase it) and the code to increase the value is, in both cases

valueSlider.value = valueSlider.value + 1;

Hey.

It would be nice to see minimal reproduction code so we can copy-paste and test.

		<NativeViewHost>
			<Slider Minimum="0" Maximum="{totalValue}" Value="{valueSlider}" Visibility="{visibleSlider}" IsEnabled="false" Color="{colorSlider}"/>
		</NativeViewHost>
var totalValue = Observable(); <--value initialised somewhere in the code
var visibleSlider = Observable();
var valueSlider = Observable();

valueSlider.value = 0;

function updateBalance(){
	valueSlider.value = 0;
	var ROOT_URL = 'xxxxx';
    fetch(ROOT_URL, myInit)
    .then(function(response){
    	if (response.status !== 200){
    		console.log('Looks like there was a problem. Status Code: ' + response.status);
    		return;
    	}

    	visibleSlider.value = "Visible";

	    //Parse the response
	    response.json().then(function(data){
	    	data.result.forEach(function(element){
				if(element.Balance !== 0){
					updateValue(element);
				}
			})
	    })
	})
    .catch(function(err){
    	console.log('Fetch error: ' . err);
    });
}

function updateValue(data){
	if(data.xxxxx){
		valueSlider.value = valueSlider.value + 1;
	}else{
		var ROOT_URL = 'xxxxxxxx';
		var encodedHeaders = {"Content-type" : "application/json"};
		var myHeaders = new Headers();
		var myInit = {
			method: 'GET',
			headers: encodedHeaders
		};

		fetch(ROOT_URL, myInit)
		.then(function(response){
			if (response.status !== 200){
				console.log('Looks like there was a problem. Status Code: ' + response.status);
				return;
			}

		    //Parse the response
		    response.json().then(function(data2){ <--Yes, data2 is used somewhere in my code
		    	valueSlider.value = valueSlider.value + 1;
		    	//Collapse slider once all things have been updated
		    	if(valueSlider.value == somevalue){
		    		visibleSlider.value = "Collapsed";
		    	}
			})
		})
		.catch(function(err){
			console.log('Fetch error: ' . err);
		})
	}
}

module.exports = {
	totalValue: totalValue,
	visibleSlider: visibleSlider,
	valueSlider: valueSlider
};

That should work. the idea is I have a button which triggers updateBalance function. The call too the API will return any number of value, currently 19 total. One of these values, at random position, will trigger the first “IF” from updateValue function.

Hey.

Sorry, but I still can’t copy-paste and run your project. You can read this section to understand how to post a bug report. Without data, it is hard to tell where is the problem.

Damn it… ok so here we are:

MainView.ux:

	<App>

		<Router ux:Name="router"/>

		<ClientPanel>
			<Navigator DefaultPath="cryptos">
				<cryptos ux:Template="cryptos" router="router"/>
			</Navigator>
		</ClientPanel>
	</App>

cryptos.ux

<Page ux:Class="cryptos">
	<Router ux:Dependency="router"/>
	
	<JavaScript File="cryptos.js">
	</JavaScript>

	<Grid Rows="auto,auto,auto,auto,auto,auto,auto">
		<Panel Dock="Top" Height="48" Color="#22b8f1">
			<Text TextAlignment="Center" Row="0" Value="Test" TextColor="White" Alignment="Center" FontSize="18" Font="Bold" />
		</Panel>
		<Grid Row="4" RowCount="1" ColumnCount="2">
			<NativeViewHost>
				<Button Column="0" Text="Update" Clicked="{update}"/>
			</NativeViewHost>
		</Grid>
		<NativeViewHost>
			<Slider Minimum="0" Maximum="19" Value="{valueSlider}" Visibility="{visibleSlider}" IsEnabled="false" Color="{colorSlider}"/>
		</NativeViewHost>
	</Grid>
</Page>

cryptos.js


var Bundle = require("FuseJS/Bundle");
var Observable = require("FuseJS/Observable");
var visibleSlider = Observable();
var valueSlider = Observable();
var colorSlider = Observable();

visibleSlider.value = "Collapsed";
valueSlider.value = 0;

/*************/
/* Functions */
/*************/
function update(){
	visibleSlider.value = "Collapsed";
	valueSlider.value = 0;
	colorSlider.value = "#22b8f1";

	console.log("Running update");
	var ROOT_URL = "http://jsonplaceholder.typicode.com/users";
	//https://reqres.in/api/users

    fetch(ROOT_URL)
    .then(function(response){
    	if (response.status !== 200){
    		console.log('Looks like there was a problem. Status Code: ' + response.status);
    		return;
    	}

    	visibleSlider.value = "Visible";
    	console.log("We retrieved content");
	    //Parse the response
	    response.json().then(function(data){
	    	//data = '{"result":[{\"user\":\"ADA\",\"Interest\":0.00000000,\"Available\":0.00000000,\"discussion\":0.00000000,\"UserAddress\":null},{\"user\":\"ARDR\",\"Interest\":1934.42475105,\"Available\":1934.42475105,\"discussion\":0.00000000,\"UserAddress\":null}]}';
	    	data.forEach(function(element){
	    		console.log("Parsing");
				//If we have a balance for this cryptocurrencie we push it to the stack
				if(element.Interest !== 0){
					updateValue(element);
				}
			})
	    })
	})
    .catch(function(err){
    	console.log('Fetch error: ' . err);
    });
}

//Update value for a particular cryptocurrency
function updateValue(data){
	if(data.user == "BTC"){
		valueSlider.value = valueSlider.value + 1;
	}else if(data.user === "UDT"){
		//Do nothing
	}else{
		var ROOT_URL = 'http://jsonplaceholder.typicode.com/users'
		var encodedHeaders = {"Content-type" : "application/json"};
		var myInit = {
			method: 'GET'
		};

		fetch(ROOT_URL, myInit)
		.then(function(response){
			if (response.status !== 200){
				console.log('Looks like there was a problem. Status Code: ' + response.status);
				return;
			}

			console.log("one by one");
		    //Parse the response
		    response.json().then(function(data2){
		    	valueSlider.value = valueSlider.value + 1;

		    	console.log("Value slider: " + valueSlider.value);
		    	if(valueSlider.value == 10){
		    		//Let's collapse
		    		visibleSlider.value = "Collapsed";
		    		console.log("We collapsed the slider");
		    	}
			})
		})
		.catch(function(err){
			console.log('Fetch error: ' . err);
		})
	}
}

module.exports = {
	visibleSlider: visibleSlider,
	valueSlider: valueSlider,
	colorSlider: colorSlider,
	update: update
};

Why the name crypto ? cause that my current topic of interest :slight_smile:
anyway, behavior on Android:

Building Android appLaunching activity 'Test'
[D6653]: Running update
[D6653]: We retrieved content
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: Parsing
[D6653]: one by one
[D6653]: Value slider: 1
[D6653]: one by one
[D6653]: Value slider: 2
[D6653]: one by one
[D6653]: Value slider: 3
[D6653]: one by one
[D6653]: Value slider: 4
[D6653]: one by one
[D6653]: Value slider: 5
[D6653]: one by one
[D6653]: Value slider: 6
[D6653]: one by one
[D6653]: Value slider: 7
[D6653]: one by one
[D6653]: Value slider: 8
[D6653]: one by one
[D6653]: Value slider: 2.995
[D6653]: one by one
[D6653]: Value slider: 3.995

Behavior on simulator:

[Viewport]: Running update
[Viewport]: We retrieved content
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: Parsing
[Viewport]: one by one
[Viewport]: Value slider: 1
[Viewport]: one by one
[Viewport]: Value slider: 2
[Viewport]: one by one
[Viewport]: Value slider: 3
[Viewport]: one by one
[Viewport]: Value slider: 4
[Viewport]: one by one
[Viewport]: Value slider: 5
[Viewport]: one by one
[Viewport]: Value slider: 6
[Viewport]: one by one
[Viewport]: Value slider: 7
[Viewport]: one by one
[Viewport]: Value slider: 8
[Viewport]: one by one
[Viewport]: Value slider: 9
[Viewport]: one by one
[Viewport]: Value slider: 10
[Viewport]: We collapsed the slider

Hey.

Try removing NativeViewHost wrapped around your Slider. Without NativeViewHost its working on my android device.

Whaou, it worked ! thank you.

The question now is why? :slight_smile:

I really don’t know the cause of this, but I could reproduce it. Here is issue ticket.