Updating cloned element when original Element is modified - javascript

I am new to Jquery and would enjoy a few leads to put me on the right track :)
Issue: I have a cart total price which is shown on another place of the page thanks to clone() and I would like to have this cloned price to auto-update each time the original price element is modified.
jQuery("document").ready(function($){
var $vartocopy = $('#totalpricemodule').clone(true);
$('.column42').append($vartocopy);
});

There are several approaches you can take from where you are facing your issue. However, there is one thing sure, JavaScript does not provide any magic that you require here and JQuery neither.
1. Move to data-centric thinking(reactive)
Long story short, your problem originates in the fact that you don't have a single source of truth(wiki) for price. It means that you are actually displaying 2 different prices which have the same value only because you mean them to. Those 2 prices have 2 representations in memory of your program and this fact is what causes all the problems you have.
Data-centric approach in your case - or reactive thinking as some people prefer - would be storing your price in JS variable/object/whatever(or generally speaking store it in memory of your JS program instead of DOM) and only at this one place. Now, whoever and whatever wants to display or use that value needs to access that variable/object/whatever.
I believe the misconception that many JS developers have is that JS code is not really a program, it's just a sugar coat over the DOM(and JQuery doesn't mitigate this). In my opinion it's wrong. One should use DOM for displaying things just as browsers do. So, store your data in memory, use JS for running code and display things via DOM.
There are many libraries out there who can make it all actually work without much difficulty. However, this is not without a cost. Firstly, you need to learn a new library, secondly you have yet another dependency and thirdly this makes your site more dependant on JS itself. Though, it's worth it. Even if just for the sake of being better programmer.
The library that I want to recommend is Vue. Not without a reason. Vue is easy to learn, lightweight, fast, doesn't force on you any "framework" and has decent documentation. Of course all of this is possible because core of Vue is not as feature-rich as other libraries but I believe it's perfect for your needs now.
With Vue you can hold your price in one variable and whenever you update that variable all places where it is used will be updated automatically. I think this is the magic that you want.
2. Create a function to update your value
Create a function like updatePrice which will update all places that need to be updated. How you will hold the references is up to you. If there are only several places you can just update them explicitly. Though, that assumes that there is only one price to display. If there are many different prices i.e. some products list then this gets only harder. In the end you might end up reinventing the wheel and create something similar to what Vue and other such libraries have to offer.
3. Eliminate problem without solving it
You can always decide that you only need this price displayed at one place eliminating the problem itself. Without problem there is nothing to solve.

Related

Should updates to Firstore items in AngularFire be done through the AngularFirestoreCollection?

In my app, I have a list that requires an "or" condition. But, as the docs say:
In this case, you should create a separate query for each OR condition and merge the query results in your app.
As a result, in my service, I'm managing two queries and surfacing them as a single observable list to consumers.
The problem comes in with updating. I have the choice of doing extra work to match up the item needing update to the correct collection so I can do the following:
myCollection.doc(item.id).update(item);
or I can make this much more simple and just:
angularFirestore.doc(`path/to/${item.id}`).update(item);
I'm operating under the assumption that the first method will result in faster updates as I'm using the same reference that it would optimistically update instantly. And that the latter will be slower in that it would be more round about by updating the persistence layer and then the collection referencing getting notified about later (probably still a small time).
All of the above is assumption, however. I back this just with a few random instances where I've seen it take a second or two for an update or delete to show up in an other part of the view, but I haven't been able to actually inspect the process.
Does anyone know if the above is correct? Should I be doing the extra work to write through the collection references or does angularfire(and/or firestore) handle this and make them effectively the same operation under the hood?
AngularFire2 is a thin wrapper around RxFire, which itself is a relatively thin wrapper around the Firebase JavaScript SDK.
There should be no significant performance difference between updating a document through AngularFire or updating it directly through the JavaScript SDK. In both cases the majority of the time is spent in the JavaScript SDK, and on the wire between the client and server. For this reason I typically update directly through the JavaScript SDK, since it's often a bit more direct and the AngularFire abstraction has little advantage for me in write operations. Given that AngularFire is built on top of this SDK, it picks up the changes instantly even when they're not made through AngularFire.
If you have an instance where this does not seem to be the case, I recommend creating a question with the minimal, complete/standalone code that reproduces that problem.

Count number comments in post in Meteor

If I want to count the number of comments a post has got, I will have to save the number of comments every time a new comment is either created or removed.
What is the most efficient and secure way to ensure the posts are updated with the number of comments every time a comment is either created or removed? I have tried Curser.observe() but it seems it causes some problems sometimes. I have looked through my code and it should be OK but sometimes some changes happend when they shouldn't so I'm afraid that observe() causes some problems when multiple objects are created at the same time.
I have looked at meteor-collection-hooks and they don't use observe. I thought observe was the best choice since it is native. How does others solve this?
Don't use observe. It consumes resources and doesn't scale past one server (in N servers are observing the change, you will have N increments). I can recommend two possible options:
hooks
As you suggested, you can use collection-hooks to modify the count. Specifically you'd probably want to use after.insert and after.remove on your Comments collection. Hooks don't require extra resources - they just patch the underlying collection code to run your callback.
Recommended reading: A Look At Meteor Collection Hooks
methods
If you use methods to insert and remove your comments, you can also modify your comment counts at the same time. This has the advantage of not requiring an external package, however it also requires some mixing of concerns in your methods.

Writing to a Firebase from within a Polymer element

I am working on an assignment for a course in "Coding the Humanities" which involves writing a custom web component. This means I am required to use Polymer even though as far as I can see there is absolutely no added value to doing so.
I want to create a literal chat "room" in which users input a character to identify themselves and can walk around the room bumping into one another after the fashion of robotfindskitten.
My idea was to write each character and its position to a Firebase location, updating everyone's positions in real time, so I need the Firebase JS client- using core-ajax for REST requests isn't fast enough.
The GitHub readme for the core-firebase element consists of a link to a less than helpful component page.
Looking at the core-firebase element itself, I don't see anything that corresponds to the 'value' event; locationChanged has a 'child-added' event handler, but that's it.
Am I crazy for thinking the core-firebase element is just very incomplete? Should I try to write my own 'value' handler? If so, do I just add it to the locationChanged property of the object passed to Polymer()? I'm very confused - I know enough JS that what's happening in the core-firebase code is straddling the limits of my comprehension. (Which might have to do with the this keyword, I don't know.) Any input here would be appreciated. (And yes, I've already remarked to the instructor that I could have handled this using plain old jQuery and Firebase if I didn't have to use Polymer. No word as yet on that.)
Looking at the commits for core-firebase it looks like it's had about two days work on it plus some maintenance, so it wouldn't be surprising if there are missing features.
One nice part about Polymer is that it interops very well with other ways of writing apps. It's totally reasonable and supported to use jQuery and Firebase directly to read from firebase and react to changes. You can still make good use of polymer's templating and databinding by doing this within an element of your own and using Polymer's data binding, templating, and plain old DOM events to propagate those changes throughout your app and render them onto the page.

Multiple Small DOM operation vs One large DOM operation

This is more a question about best practices. When trying to apply MVC-like design pattern in a web application, I often find myself wonder how I should go about updating the View.
For example, if I am to update View_1 who has X number of elements. Is it better to:
A: iterate through each of the X elements, figuring out which ones need to be updated and apply the DOM change at a very fine granularity.
or
B: using the data supplied by Model or some other data structure to regenerate the markup for this entire View and all its enclosing elements, and replace the root element of View_1 in one DOM manipulation?
Correct me if I am mistaken. I heard that rendering engines are usually more efficient at replacing at large chunk of the DOM in one go, than multiple smaller DOM operations. If that is the case then approach B is superior. However, even using template engines, I still sometimes find it difficult to avoid rewrite markups for parts of the view that aren't changed.
I looked into the source code for project Bespin before the renamed it. I distinctly remember that they implemented some sort of rendering loop mechanism where DOM operations are queued and applied in fixed time intervals, much like how games manage their frames. This is similar to Approach A. I can also see the rationales behind this approach. The small DOM operations applied in such manner keeps the UI responsive (especially important for a web text editor). Also this way, the application can be made more efficient by only update the elements that needs to be changed. Static text and aesthetic elements can remain untouched.
Those are my arguments for both sides. What do you guys think? Are we looking for a happy medium somewhere, or one approach is by and large superior?
Also, are there any good books/papers/sites on this particular topic?
(let's assume the web app in question is interaction heavy with many dynamic updates)
It's true that rendering engines usually handle change in large chunks faster than multiple small changes.
tl;dr: The bespin way would be ideal, and if you can, do it in a worker.
Depending on the size of the amount of changes you might want to try to start a worker and do the calculation of the changes inside the worker since long running JS lock up the UI. You might consider using the following flow:
Create a object with a part of the dom tree and also the parent id.
Stringify the object to JSON
Start a worker
Pass in the stringified object into the worker
Receive and parse the string.
Work on changing all the necessary parts of the dom tree that you passed in.
Stringify the object again.
Pass the object back to the main thread.
Parse and extract new dom tree.
Insert into the dom again.
This will be faster if there are many changes and a small tree. If it's a big tree and few changes just doing the changes locally in a copy of the real DOM tree will be faster and then updating the DOM in one go.
Also read googles sites about page speed:
https://code.google.com/speed/articles/
And especially this article:
https://code.google.com/speed/articles/javascript-dom.html
After 3 years of working with various web technologies, I think I finally found a great balance between the two approach: virtual DOM
Libraries like vdom, Elm, mithril.js, and to some extend Facebook React track a thin abstraction of the actual DOM, figures out what needs to be changed, and tries to apply the smallest possible DOM change.
e.g.
https://github.com/Matt-Esch/virtual-dom/tree/master/vdom

how do you folks handle complex state situations where order of operations is important?

I'm getting in to a situation where I have several interacting widgets (on a web UI), all of whom can be in multiple different states, and whose behavior depends on others the others. I'm running in to situations where, for example, a set of data gets sorted twice, or the data gets displayed before it's sorted, rather than the other way around. It's a little bit of a wack-a-mole problem, where I think I've simplified things and gotten it working, only to find out I've broken things somewhere else.
I have functions that do things like:
widgetAFunction
load data into widget B
tell widget B to sort the data
tell widget B to display the data
My love of code reuse makes me want to do something like write a loadData function in widget A that goes something like this:
widgetBLoadDataFunction
update data
sort the data
refresh the view
So that all widgetA has to do is call one function on widgetB. But then there are cases where I just want to sort the data, without updating the data, so I write:
widgetBSortFunction
sort the data
refresh the view
And then maybe I want a filter function
widgetBFilterFunction
filter the data
refresh the view
And maybe I want to be update the data but not sort it, so I have
widgetBNoSortLoadDataFunction
update data
refresh the view
It doesn't seem that complex, but I wind up with these really long, very brittle chains of function calls, or a bunch of very similar calls. As Martin Fowler would say, the code is getting a little smelly.
So, what other alternatives do I have? I did something on a recent project where I did a state machine kind of thing, where I registered a bunch of functions with a set of conditions, or states which would trigger their execution. That worked somewhat well, and I'm thinking that approach might be good to use again.
Does anyone know what I'm talking about here, and even better, can anyone point me toward some patterns that will help me get my head around this better?
What you need is a finite state machine implementation. Basically every finite state machine needs:
Events that the program responds to
States where the program waits between events
Transitions between states in response to events
Actions taken during transitions
Variables that hold values needed by actions between events
A good article from IBM teachs you a way of implementing it by means of Javascript.
Edit: Here is a FSM builder, so you don't have to build your own.
Fernando already mentioned FSMs, and gave good info and links. :)
In addition, I'll add that your classes should already incorporate enough state so that you're not worried about sorting twice, etc. I.e., widgetB.sort() should check if it's been sorted since last update and just return if so. There's practically no downside to doing this, and it can improve performance (and also guard consistency).

Categories