Making component based api calls easier: better watch syntax

computed-properties
components
watchers

#1

Working with vue, I have found that fetching data or making changes off of props/router parameters is unnecessarily verbose.

Below is a typical current setup for a component that accepts an id (and makes an api call with it) and can be passed this id as prop from either a router param or parent component.

export default {
	created: function () {
		this.refresh();
	},
	data: function() {
		return {
			item: undefined
		}
	},
	methods: {
		refresh: function () {
			// option for intermediary state ex: this.item = "refreshing"
			// option for side effects ex: this.emit('updated', this.id)
			this.item = api.items.read(this.id); // opportunity for async update
		}
	},
	watch: {
		'id': function () { // explicit watch
			this.refresh();
		}
	},
	props: ['id']
};

In the above example, we use a watcher because: we need to guarantee that the api call is made whenever the id prop changes, we need control over intermediary state (not allowed in computed), we need side effects (not allowed in computed), and we need async (not allowed in computed).

In the below example a computed function would ideally have these powers - but with the output and simplicity of a computed function:

export default {
	props: ['id'],
	computed: {
		item: {
			observe: [id], // explicit watch
			lazy: false, 
			async: true,
			value: function () {
				// put intermediary state or side effect functions here
				return api.items.read(this.id); // async/await magic on return val
			}
		}
	}
};

Thoughts on this as an alternate/optional more powerful syntax for computed props?


#2

Well, it mixes a lot of different concepts into one, basically trying to make computed do everything. I don’t feel like this will make code more understandable.

E.g. using a computed in a template, people would have to know wether it’s async or not to know wether it may or may return a promise instead of actual values (rendering is synchronous, remember!)

Also, explicitly defining observed properties is unnecessary as comuted props what all reactive dependencies anyway.

If you don’t want it to be lazy, use a method.


#3

I will get back to this with some more detailed reasons in a bit defending computed - but for the sake of this discussion it isn’t critical.

I don’t think I have the perfect answer…but there is a simple scenario of making an api call off a prop and consuming that result in a template. Simple scenario, complicated execution currently as shown above.

I am suggesting that there should be a simple way to make this simple scenario happen. Do you have any alternate ideas? I have hundreds of components that essentially call an api and consume the result. It’s extremely verbose to write:

  • a method
  • several watchers
  • a data object
  • a created hook

(4+ concepts to setup) to essentially accomplish what could be done in 1 concept.

I am not particularly attached to the implementation as long as I don’t have to write more code than this to accomplish an api call:

item: function () {
    return api.items.read(this.id); // async
}