LoveAndHappiness
LoveAndHappiness

Reputation: 10135

Javascript: Remove Item from Array

While using Vue.js I have a function that will remove all arhived tasks, but I don't know how to remove the item from the array.

I tried calling the remove function inside of the removeAllArchived method, but it won't execute properly.

Also just calling the this.$remove(task) doesn't work.

new Vue({
	el: '#todo',

	data: {
		tasks: [
			{ 'task': 'Eat breakfast', 'completed': false, 'archived': false },
			{ 'task': 'Play with Klea', 'completed': false, 'archived': false },
			{ 'task': 'Code some stuff', 'completed': false, 'archived': false }
		],

		newTask: ''
	},

	methods: {
		toggleTaskCompletion: function(task) {
			task.completed = ! task.completed;
		},

		addTask: function(e) {
			e.preventDefault();

			this.tasks.push({
				'task': this.newTask,
				'completed': false,
				'archived': false
			});

			this.newTask = '';
		},

		editTask: function(task) {
			this.tasks.$remove(task);

			this.newTask = task.task;

			// focus on input field
			this.$$.newTask.focus();
		},

		archiveTask: function(task) {
			task.archived = true;
		},

		removeTask: function(task) {
			this.tasks.$remove(task);
		},

		completeAll: function() {
			this.tasks.forEach(function(task) {
				task.completed = true;
			});
		},

		removeAllArchived: function() {
			this.tasks.forEach(function(task) {
				if(task.archived == true) {
					console.log(task.task);
					delete(task);
				}
			});
		}
	},

	filters: {
		inProcess: function(tasks) {
			return tasks.filter(function(task) {
				return ! task.completed && ! task.archived;
			});
		},

		inDone: function(tasks) {
			return tasks.filter(function(task) {
				return task.completed && ! task.archived;
			});
		},

		inArchive: function(tasks) {
			return tasks.filter(function(task) {
				return task.archived;
			});
		}
	},

	computed: {
		completions: function() {
			return this.tasks.filter(function(task) {
				return ! task.completed && ! task.archived;
			});
		},

		done: function() {
			return this.tasks.filter(function(task) {
				return task.completed && ! task.archived;
			});
		},

		archived: function() {
			return this.tasks.filter(function(task) {
				return task.archived;
			});
		}
	}

});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.5/vue.min.js"></script>

	<div id="todo">

		<h1>Vue Todo</h1>


		<div class="row">
			<div class="col-xs-12">
				<form v-on="submit: addTask">
					<div class="form-group">
						<label for="name">Add Todo:</label>
						<input type="text" name="name" id="name" class="form-control" v-model="newTask" v-el="newTask">
					</div>

					<div class="form-group">
						<button type="submit" class="btn btn-primary">Add Task</button>
					</div>				
				</form>
			</div>
		</div>
		

		<div class="row">
			<div class="col-xs-12 col-sm-6 col-md-4">
				<h2>Todo <small v-if="completions.length">({{ completions.length }})</small></h2>
				<table class="table">
					<thead>
						<tr>
							<th>Task</th>
							<th>Options</th>
						</tr>
					</thead>
					<tbody>
						<tr v-repeat="task: tasks | inProcess">
							<td>{{ task.task }}</td>
							<td>
								<buttn class="btn btn-xs btn-success" v-on="click: toggleTaskCompletion(task)">Complete</buttn>
								<buttn class="btn btn-xs btn-primary" v-on="click: editTask(task)">Edit</buttn>
								<buttn class="btn btn-xs btn-danger" v-on="click: archiveTask(task)">Archive</buttn>
							</td>
						</tr>
					</tbody>
				</table>			
			</div>
			<div class="col-xs-12 col-sm-6 col-md-4">
				<table class="table">
					<h2>Done <small v-if="done.length">({{ done.length }})</small></h2>
					<thead>
						<tr>
							<th>Task</th>
							<th>Options</th>
						</tr>
					</thead>
					<tbody>
						<tr v-repeat="task: tasks | inDone">
							<td>{{ task.task }}</td>
							<td>
								<buttn class="btn btn-xs btn-success" v-on="click: toggleTaskCompletion(task)">Uncomplete</buttn>
								<buttn class="btn btn-xs btn-danger" v-on="click: archiveTask(task)">Archive</buttn>
							</td>
						</tr>
					</tbody>
				</table>			
			</div>
			<div class="col-xs-12 col-sm-6 col-md-4">
				<h2>Archived <small v-if="archived.length">({{ archived.length }})</small></h2>
				<table class="table">
					<thead>
						<tr>
							<th>Task</th>
							<th>Options</th>
						</tr>
					</thead>
					<tbody>
						<tr v-repeat="task: tasks | inArchive">
							<td>{{ task.task }}</td>
							<td>
								<buttn class="btn btn-xs btn-danger" v-on="click: removeTask(task)">Remove</buttn>
							</td>
						</tr>
					</tbody>
				</table>			
			</div>
		</div>

		<div class="row">
			<div class="col-xs-12">
				<button class="btn btn-warning" v-on="click: completeAll">Complete All</button>
				<button class="btn btn-danger" v-on="click: removeAllArchived">Remove All Archived</button>
			</div>
		</div>
		<pre>{{ $data | json }}</pre>
	</div>

removeAllArchived: function() {
    this.tasks.forEach(function(task) {
        if(task.archived == true) {
            console.log(task.task);
            // remove task
        }
    });
}

How do I make the button "Remove All Archived" work?

Upvotes: 0

Views: 189

Answers (2)

MinusFour
MinusFour

Reputation: 14423

I think you need to remove the property directly from the array, you don't get anything removing the reference out of the parameter.

removeAllArchived: function() {
    this.tasks.forEach(function(task, index) {
        if(task.archived == true) {
            console.log(task.task);
            delete(this.tasks[index]);
        }
    });
}

Might be better if you filter out the array:

removeAllArchived: function() {
    this.tasks = this.tasks.filter(function(task){
         return task.archived !== true;
    });
}

Edit: It cleaned out non archived. Now it removes archived.

Upvotes: 1

Mark Schultheiss
Mark Schultheiss

Reputation: 34168

You can use slice, or I like and use this snip from here: http://ejohn.org/blog/javascript-array-remove/

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Upvotes: 1

Related Questions