UX: Display last item in list

I need to show only the last item in a list in my ux, so I made a function like this:

module.exports = {
    ...

    lastItem: function (arg) { return arg.data.list.getAt(arg.data.list.length - 1).thing },

    ...
}

    ...
    <Text Value="{lastItem}" />
    ...

Assuming all the context is correct (i’ve simplified this from a more complex data structure with <Each> tags, why is my output in preview: Fuse.Scripting.V8.Function

IF I set the function out like this:

var lastItem = function() {
    return "anything";
}

it STILL doesn’t work, BUT:

var lastItem = Observable(function() {
    return "anything";
}

DOES WORK.

Finally,

var lastItem = Observable(function(arg) {
    return arg.data.list.getAt(arg.data.list.length - 1).thing;
}

Actually just crashes because the arg never ‘reaches’ the function. While I CAN just make a value built into the data structure that is equal to the last value, it’s a pain to implement this because I have to get it saved and then load it, and deal with all the bugs that come with that and also I would need to constantly be updating it, why can’t I use a function like this?

Thanks

Hi,

This function gives you an observable of the last item in another observable:

function last(obs)
{
    return Observable(function() {
        return obs.getAt(obs.length-1);
    })
}

Hey,

That function still shows up as Fuse.Scripting.V8.Function in the UX. :frowning:

bump. This has been marked as solved but it hasn’t :frowning:

I believe this should be simpliefied to:

function last(obs) {
    return Observable(obs.getAt(obs.length-1));
}

The thing is @Fudge what is in your observable, functions?

Edwin’s answer is not correct.

My answer above is correct. If it doesn’t work, there must be something else wrong. Can you provide a full test case please?

Oh because he wants one that is always tied to the observable being passed right @Anders ?

Made a little test app on the topic, maybe this helps.

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

    var last_id = 1;
    function Item(title) {
        this.id = last_id;
        this.title = title;
        last_id++;
    };

    var list = Observable();
    list.add(new Item('test one'));
    list.add(new Item('test two'));
    list.add(new Item('test three'));

    function addItem() {
        var tmp = list.toArray();
        tmp.push(new Item('new item ' + (last_id)));
        list.replaceAll(tmp);
    };

    function delItem(args) {
        list.forEach(function(item,index) {
            if (item.id == args.data.id) list.removeAt(index);
        });
    };

    var last = list.map(function(item, index) {
        return {'item':item,'index':index};
    }).where(function(obj) {
        if (obj.index == (list.length - 1)) return true;
        return false;
    }).map(function(obj) {
        return obj.item;
    });

    module.exports = {
        'list': list,
        'last': last,
        'addItem': addItem,
        'delItem': delItem
    };
    </JavaScript>
    <ClientPanel Background="#eee">
        <Grid Rows="auto,1*">
            <Panel>
                <StackPanel>
                    <Panel Height="80">
                        <Panel Width="70%" Height="50" Background="#999" HitTestMode="LocalBoundsAndChildren">
                            <Text Alignment="Center" Value="Add item" />
                            <Clicked>
                                <Callback Handler="{addItem}" />
                            </Clicked>
                        </Panel>
                    </Panel>
                    <Panel Height="80">
                        <Grid Columns="1*,10,1*" Width="70%">
                            <Text Alignment="CenterRight" Value="Last item:" />
                            <Panel />
                            <Text Alignment="CenterLeft" Value="{last.title}" />
                        </Grid>
                    </Panel>
                </StackPanel>
            </Panel>
            <StackPanel ItemSpacing="1">
                <Each Items="{list}">
                    <DockPanel Background="#fff" Height="50">
                        <Text Alignment="Center" Value="{title}" />
                        <Panel Dock="Right" Width="50" HitTestMode="LocalBoundsAndChildren">
                            <Text Alignment="Center" Value="Del" />
                            <Clicked>
                                <Callback Handler="{delItem}" />
                            </Clicked>
                        </Panel>
                    </DockPanel>
                </Each>
            </StackPanel>
        </Grid>
    </ClientPanel>
</App>

Thanks for the answers.

I feel like I should clarify here, the context is all coming from the UX and the function is being used like this:

<Text Value="{last}" />

Here’s a test case:

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


        function myItem() {
            this.subList = Observable("wrong", "wrong", "correct");
        }

        var myList = Observable(new myItem, new myItem, new myItem);

        function last(obs) {
            return Observable(function() {
                return obs.subList.getAt(obs.subList.length-1);
            });
        }

        module.exports = {
            myList: myList,
            last: last
        }
    </JavaScript>

    <DockPanel>
        <Each Items="{myList}">
            <Text Value="{last}" Dock="Top" Margin="20" />
        </Each>
    </DockPanel>

</App>

You have to call the last function with the observable in question. Now you are just exporting the function.

module.exports = {
    myList: myList,
    last: last(myList)
}

Hey,

Does the function need to be changed too? Now I get no output at all

Yes, please use the function exactly as I originally wrote it.

I did, it doesn’t work, even without trying to access the sublist, please try running the minimal test case and getting “correct” to display

Upon reading your code closer, you are not trying to display the last item of a list, you are trying to display the last item in each list in a list. That complicates things a little

To do that, do a map using the last-function:

module.exports = {
    list: myList.map(last)
}

Then simply Each over list and display {}

Hi,

Sorry this has dragged out, but can you please run my minimal example case? It just doesn’t seem to work for me when I add in your code.

Thanks

Hi,

This code works:

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


        function myItem() {
            this.subList = Observable("wrong", "wrong", "correct");
        }

        var myList = Observable(new myItem, new myItem, new myItem);

        function last(obs) {
            return Observable(function() {
                return obs.getAt(obs.length-1);
            });
        }

        module.exports = {
            myList: myList.map(function(x) { return last(x.subList); })
        }
    </JavaScript>

    <DockPanel>
        <Each Items="{myList}">
            <Text Value="{}" Dock="Top" Margin="20" />
        </Each>
    </DockPanel>

</App>