Tienus McVinger
Tienus McVinger

Reputation: 477

NativeScript: UI won't show removed item from an ObservableArray without refresh

First of, I'm very new to NativeScript. I followed a tutorial for a ToDo list found here https://x-team.com/blog/build-simple-todo-list-mobile-application-nativescript/, and as a little exercise for myself I wanted to add a remove function for the tasks inside a list.

Here's my code:

Tasks.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo">  
<Page.actionBar>
    <ActionBar title="Tasks">
        <ActionBar.actionItems>
            <ActionItem text="New" tap="{{ insert }}" ios.position="right" />
            <ActionItem text="Delete" tap="{{ delete }}" ios.position="right" />                
        </ActionBar.actionItems>
    </ActionBar>
</Page.actionBar>
<ListView items="{{ tasks }}"></ListView>

tasks-view-model.js

var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;  
var Sqlite = require("nativescript-sqlite");  
var Dialogs = require("ui/dialogs");

function createViewModel(database, listId) {  
    var viewModel = new Observable();
    viewModel.tasks = new ObservableArray([]);
    viewModel.listId = listId;

    viewModel.insert = function() {
        Dialogs.prompt("Task Name", "").then(result => {
            database.execSQL("INSERT INTO tasks (list_id, task_name) VALUES (?, ?)", [this.listId, result.text]).then(id => {
                var _string = "ID: " + id + ", " + result.text;
                this.tasks.push(_string);
            }, error => {
                console.log("INSERT ERROR", error);
            });
        });
    }

    viewModel.select = function() {
        this.tasks = new ObservableArray([]);
        database.all("SELECT id, task_name FROM tasks WHERE list_id = ?", [this.listId]).then(rows => {
            for(var row in rows) {
                var _id = rows[row][0];
                var _item = rows[row][1];
                var _string = "ID: " + _id + ", " + _item;
                this.tasks.push(_string);
            }
        }, error => {
            console.log("SELECT ERROR", error);
        });
    }

    viewModel.delete = function() {
        Dialogs.prompt("Task ID", "").then(result => {
            database.execSQL("DELETE FROM tasks WHERE id = ?", [result.text]).then(id => {
               Dialogs.prompt(id);
            }, error => {
                console.log("DELETE ERROR", error);
            });
        });
    }

    viewModel.select();

    return viewModel;
}

exports.createViewModel = createViewModel;  

The actual deleting of the item when passing its ID works fine. However the UI doesn't show this change without me manually refreshing it, and I cannot figure out why. In case it matters, I'm running this on an Android emulator.

Thanks in advance for your help.

Upvotes: 1

Views: 281

Answers (1)

JoshSommer
JoshSommer

Reputation: 2618

Inside your delete function you also need to remove the item from the ObservableArray.

viewModel.delete = function() {
    Dialogs.prompt("Task ID", "").then(result => {
        database.execSQL("DELETE FROM tasks WHERE id = ?", [result.text]).then(id => {
           Dialogs.prompt(id);

            /// remove the item from the observable array.
           this.tasks.splice(INDEX_OF_THE_ITEM_DELETED,1);


        }, error => {
            console.log("DELETE ERROR", error);
        });
    });
}

You may want to consider changing the ObservableArray of tasks from an array of strings to an array of Objects with an id property and value property. So it's easier to determine the index of the item you want to remove. If not you will have to rebuild value that is pushed into the array to find the index.

Upvotes: 2

Related Questions