Backbone.js 'add' and 'sync' events are redundant - backbone.js

I have a SPA app that's a blogging app of sorts. You post, and then the 'feed' composite view puts the post on top.
What I envision:
1. have a sync listenTo on the post collection that, on the collection fetch(), loads all the posts.
2. have an add listenTo on the collection that will render a new post when it's added.
The problem is that on fetch(), I'm getting both add and sync events which causes duplicate posts.
What do you all suggest I do?
Thanks!

When you call fetch() for the first time on an empty collection, the collection will fire an add event for all new models, so listening for that should be enough.
When you call fetch() when the collection already has models, you will only get an add event for new models.

Related

How do I link and transfer data from one page to another in reactjs? (Not using render bc it doesn't work for me)

I need to transfer data from an API from one page to another, I've tried various different methods and this is what I currently have, but it doesn't work, obviously I have a button created as well - Any other ideas inside of reactjs?
const navigate = useNavigate();
const onClick = () => navigate(/pageIGoTo/${variable.id});
One option that works well, and is easy to inplement, is to include a ViewModel object in the Props object when creating views. See this code of mine for an example.
Use of shared objects within view models enables view 1 to update data and for view 2 to then have access to the same data immediately. Note that React may recreate views frequently, but this does not affect view models.
If you want view 2 to refresh immediately, then you will need an event based mechanism. Eg view 1 raises an event, view 2 receives it and updates its state. See the use of these events in my app for an example.

How To refetch all the model inside a model in just one trigger without using loop

Hi I have question regarding refetching of the model on backbone
is there a way to fetch all model in a model
basically if i have my model and if that said model has an attribute of model as well i could trigger a re fetch and all the model inside that model will be re fetched
my current process is i would loop all through the attribute of a model and look for a model if i could find any i would fetch it. do you have a better way to do things? any suggestions?
This is my current code
_.each(self._getModels(entityRecordModel.attributes), function (model)
{
model.fetch();
});
The pub/sub pattern can help you here.
When you first initialised the attribute models, just subscribe to the main model's sync event and then fetch them as well.
If you want to to all this in one request, then use model's parse method to initialise/reset the attribute models.

Backbone listenTo timeout

I am connected to a web socket and constantly updating my model based on the incoming JSON objects.
Using this coffeesScript code:
#listenTo #model, 'change', #render
I am listening for every moment that the model is updated and then I render that newly updated model. This works well. However, I would now like to set a timeout so that if the listener doesn't detect a model update after 30 seconds, I can call a different function and update my model with a timeout message. What is the best way set up this timeout?
I think you should add callbacks at where you send ajax requests. When you listen to a model's change event, you don't know when the request is sent.
What if you want to add features like auto-refresh? In that scenario 'change' event is listened once but there could be multiple requests that can timeout. These are separated things.

Don't call render() if the View itself updated Model via Backbone.Model.set()

In my Backbone.js project I have one Model and several Views. All Views have registered callbacks for 'change:currentTextTitle' on this model:
// 'this' stands for any of the Views here
myModel.on('change:currentTextTitle', this.render, this);
Now a user performs some action, which causes the specific View to change its "current text title" field. This specific view then calls myModel.set("currentTextField", newTextValue) which in turn triggers the 'change:currentTextTitle' event calling all Views (including the one from which set() originated). Then all Views call their render callback functions.
The problem is that the render method is also called on the View from which the set()-Method was originally called, which is completely unnecessary because it is already up-to-date with currentTextTitle.
How would my Views call myModel.set() in a way that the other Views' callbacks get informed, but without triggering/calling the "source View" itself?
One workaround seems to be to pass the source view as part of the options parameter of the set() method (which gets passed along to trigger() and then along the the render() callback):
myModel.set("currentTextField", newTextValue, thisViewSetAttribute)
Then in the render callback one could check if thisViewSetAttribute != this. However, instead of implementing checks in every callback, I think it would make more sense to handle this in the Model itself by only calling the necessary callbacks and ignoring the source View from which the set() method call originated. Is this possible?
I think the 'proper' MCV solution is that your views should not know or care how the model changed, they should simply handle the change and update accordingly. If they are already current, the user shouldn't know the difference.
I definitely would not pass the source view to the model. Instead when the model changes, you could just have the view check if it is current and not re-render. But if the extra render doesn't cause any issues then just let it happen :)
In Backbone, the 'view' is both view and controller. So try to treat the change as 2 separate steps. First, convert user input into changes on the model, then as a separate step (initiated by model change event), handle that change and update the view. If each view does this, no matter how the model changes, everything will stay up-to-date.

when the add event is fired in backbonejs?

When does the 'add' event gets fired in a collection?
I am in a notion that when i execute something like app.mycollection.create(this.newAttributes()); the add event will be fired.
Actually i do this while initializing a view
window.app.mycollection.on('add',this.render,this)
So ideally, first there should be a post request (when i do a create) and then the get request (my render function fetches rows from backend). But in network console, i get the opposite. I first see a get request and then the post request.
This made me thought that 'add' event gets fired immediately after a call to create method without waiting for creation to be complete.
This thus fetches me old data without including the data that has just been created.
Please shed some light.
You have executed render function immediately. Try update your code:
window.app.mycollection.on('add', this.render, this)
EDIT
Take a look
Creating a model will cause an immediate "add" event to be triggered
on the collection, a "request" event as the new model is sent to the
server, as well as a "sync" event, once the server has responded with
the successful creation of the model. Pass {wait: true} if you'd like
to wait for the server before adding the new model to the collection.

Resources