Styling

I’m building a small app as a way of learning Fuse Tools and used the ‘News Feed’ exmample as a starting point.

My JSON (from an external API I have no control over) contains fixtures and results for football games.

All the finished games have the correct scores while game that haven’t been played yet have scores of -1, -1.

I don’t want to display a score if it’s value is -1, since is this isn’t a real score. So can I hide the node based on its value?

Is it better to parse the JSON response first creating Observables from everything I want to display. Or is there a way to change the stlye of a node depending on its value after I’ve displayed everything.

Hi!

There are a lot of ways to do this, but I think the quickest way to do it if you want to get to the goal is to do JS manipulation of the data. Something like this does it:

<App>
    <JavaScript>
        var Observable = require('FuseJS/Observable');

        var observableData = Observable(
            { score1: 50, score2: 49},
            { score1: -1, score2: -1},
            { score1: 12, score2: 4});

        var filteredSource = observableData.where(function (match)
        {
            return !(match.score1 === -1 && match.score2 === -1);
        });

        module.exports = {
            data: filteredSource
        };
    </JavaScript>
    <StackPanel>
        <Each Items="{data}">
            <Grid ColumnCount="2">
                <Text Value="{score1}" />
                <Text Value="{score2}" />
            </Grid>
        </Each>
    </StackPanel>
</App>

Hopefully it is simple to piece this together with the datasource you’re working with.

If you wanted to do different styles based on whether or not you have the final result, you could go with something like:

<App>
    <JavaScript>
        var Observable = require('FuseJS/Observable');

        var observableData = Observable(
            { score1: 50, score2: 49},
            { score1: -1, score2: -1},
            { score1: 12, score2: 4});

        var filteredSource = observableData.map(function (match)
        {
            return {
                score1: match.score1,
                score2: match.score2,
                finalResult: !(match.score1 === -1 && match.score2 === -1)                
            };
        });

        module.exports = {
            data: filteredSource
        };
    </JavaScript>
    <StackPanel>
        <Each Items="{data}">
            <Panel>
                <Match Value="{finalResult}">
                    <Case Bool="true">
                        <Grid ColumnCount="2">
                            <Text Value="{score1}" />
                            <Text Value="{score2}" />
                        </Grid>
                    </Case>
                    <Case Bool="false">
                        <Text>Still awaiting result for this match</Text>
                    </Case>
                </Match>
            </Panel>
        </Each>
    </StackPanel>
</App>

In this way, you basically annotate the result with a calculation. Read more about Match and Case here

I’d like to add +1 for the first answer; while both are valid (and great examples of both scenarios you describe), using observables in this way makes things much more readable and explicit :slight_smile:

Hi, thanks for replying.

I think I should have included some example JSON here.

The JSON I have is an array of fixtures, each fixture looks like this:

http://api.football-data.org/docs/latest/index.html#fixture

The result object is nested in the fixture object. So I can’t use a map function to remove it (I think).

I’ve used the match - case format to do what I want.

Is there still a way to do it with Observables?

Thanks for your help.

I took a look at the original data, and pulled some down myself. The format is:

{
    "fixture":{
        "_links":{
            "self":{
                "href":"http://api.football-data.org/alpha/fixtures/133566&quot;
            },
            "soccerseason":{"href":"http://api.football-data.org/alpha/soccerseasons/347"},
            "homeTeam":{"href":"http://api.football-data.org/alpha/teams/556"},
            "awayTeam":{"href":"http://api.football-data.org/alpha/teams/514"}},
            "date":"2013-10-04T22:00:00Z",
            "status":null,
            "matchday":10,
            "homeTeamName":"Nîmes Olympique",
            "awayTeamName":"SM Caen",
            "result":{"goalsHomeTeam":2,"goalsAwayTeam":1}
        },
        ...

So, if your data is just an array of those fixtures, changing COCPORN’s original code to the following should work, given you “expand” the array into an Observable as shown:

    // Fetch the data (an array of fixtures)
    var originalData = fetch(...);
    // Place the single array into an Observable
    // Note that this Observable's value can be updated at any time
    var observableData = new Observable(originalData);
    // Project the array's contents into multiple values in another Observable (see https://www.fusetools.com/learn/fusejs#-expand-expand-func- )
    var fixtures = observableData.expand();
    var filteredFixtures = fixtures.where(function (fixture)
    {
        var result = fixture._links.result;
        return !(result.score1 === -1 && result.score2 === -1);
    });

Note that you don’t have to actually bind all these different Observables to variables; I only did that for clarity. Doing something like new Observable(...).expand().where(...) is perfectly fine :slight_smile:

I’ve tried to use this in my code and i got a slight problem with it. So what i’m doing is

var foo = Observable(
    {x:'bar',y:'rab'},
    {x:'baar',y:'raab'}
);
var somedata = foo.map(function(match) {
    return {
        x: match.x,
        y: match.y               
    };
});
module.exports = {
    data: somedata
};

<Each Items="{data}">
    <Grid ColumnCount="2">
        <Text Value="{x}" />
        <Panel>
            <Match Value="{y}">
                <Case String="rab">
                    <Text Value="A" />
                </Case>
                <Case String="raab">
                    <Text Value="B" />
                </Case>
            </Match>
        </Panel>
    </Grid>
</Each>

If i do it like that, i always get on accessing the panel it’s used in Unable to parse data: * (I’m not sure if it is a * at the end, but it looks like it)

It seems to work anyway, but as it tells me that something went wrong and it might affect the stability of the app somehow, i’d like to fix it. Any ideas what might cause this warning?

iUseFuse: Hard to tell what that means if you don’t provide a complete test case. Did you test this with version 0.10 ?

Yes, did test it with the 0.10 - still the same. Seems that i have to find another way to nest loops where the inner loop does use data from the outer loop.