Thanks again, Clark. Your suggestion led me to turn my attention to mithril, something I should have done on a larger scale before. And the solution turned out to be much, much easier. app.store.find
ing the data I needed filled the app.store
, so a simple m.redraw()
was all I needed to render the data into the application.
In case you are wondering what my extension will do: It is an extension that adds additional event posts, in this case when a post is deleted or restored. The event posts store the ID of the hidden/restored post and a value for hidden (1: hidden, 0: restored). Since the post in question may be missing from app.store
, I sometimes need to load additional data about this post. This data can be accessed (the user has the right to view the deleted post, the post can be viewed after a restore) or not. These cases must be covered.
Well, this is the javascript component I finally came up with:
import EventPost from 'flarum/components/EventPost';
import humanTime from 'flarum/helpers/humanTime';
export default class PostHiddenPost extends EventPost {
icon() {
return this.props.post.content().hidden
? 'far fa-trash-alt'
: 'fas fa-recycle';
}
descriptionKey() {
const post = this.props.post;
const hiddenPost = app.store.getById('posts', post.content().id);
return hiddenPost && hiddenPost.id()
? (post.content().hidden
? 'pollux-elogger.forum.post_stream.post_hidden_text'
: 'pollux-elogger.forum.post_stream.post_restored_text')
: (post.content().hidden
? 'pollux-elogger.forum.post_stream.post_unknown_hidden_text'
: 'pollux-elogger.forum.post_stream.post_unknown_restored_text');
}
descriptionData() {
const post = this.props.post;
const hiddenPost = app.store.getById('posts', post.content().id);
if (hiddenPost && hiddenPost.id()) {
return {
a: <a class="PostMention" data-id={hiddenPost.id()} href={app.route.post(hiddenPost)} />,
number: hiddenPost.number(),
poster: <a className="EventPost-user" href={app.route.user(hiddenPost.user())}>
{hiddenPost.user().username()}
</a>,
date: humanTime(hiddenPost.createdAt())
};
} else {
return app.store.find('posts', { 'filter[id]': post.content().id })
.catch(function(e) {
console.error("Catch 'find' error: " + e.message);
})
.then(function(data) {
if(data.length) {
m.redraw();
}
});
}
}
}
This code works fine. If the hidden post is not in app.store
, the event post will show the description according to the post_unknown_hidden_text
key, then if the post could be loaded (asynchronously), the description will change to post_hidden_text
. Great? No, not quite.
Suppose a post is deleted and then restored shortly afterwards, then there are two event posts. If the data for this post has to be loaded via app.store.find
, this happens twice, because the asynchronously loaded data of the first event post is not yet there when the second event post is rendered. Two times app.store.find
and twice a redraw. Should there be another deleted post in our example whose data cannot be loaded (post not restored, user not privileged), then there will be even three app.store.find
attempts (once initially and again with each redraw).
How could I avoid this unnecessary traffic?