I am using rxjs in a project, the problem I face is that both myBehaviorSubject.value and myBehaviorSubject.getValue() returns the last item pushed into the observable by reference. Can I somehow get that last item by value?
Note: I know I can copy the object with Object.assign but that seems like boilerplate code to me. I am looking for some official method or piece of code what extends it to support this functionality. So what I want to do is something like myBehaviorSubject.getValueByValue() (Sounds strange, I know.)
No, there is nothing in rxjs that does this, and this isn't really in the Rx domain. While observables work best when used with immutable types, rxjs doesn't provide any features in this area. For simple object cloning you can, as you suggest, use something like Object.assign. For collections, I recommend immutable.js. You can (as suggested in the comments) extend BehaviorSubject yourself to include whichever implementation you prefer.
Related
I'm writing a React component that I intend to make public, and I'd like to have it play nice either with JS arrays/objects, or immutable.js equivalents (Map/List).
What's the best way to identify an Immutable.js Map or List? I don't want to simply use Array.isArray, because I do want to enforce that it is either an Array or a List, for example.
I could just check for some of the Immutable.js properties, like _origin or __ownerID, but I don't want to depend on internal APIs that are subject to change in minor versions.
I would very much recommend the suggestions given by #robg and #joseph-the-dreamer. However, just for the sake of answering your exact need, for every Immutable.Type there is a Immutable.Type.isType() static function which you can use to determine if a given object is of that type.
E.g. Map docs -
var im = require("immutable");
if (im.Map.isMap(someObjectWhichMayBeMap)){
...
}
I'm writing a compiler in JavaScript, and for the optimizer I'm following the usual pattern where a list of optimizations is run repeatedly until nothing happens. The obvious way to detect the 'nothing happens' condition is to have each optimization set a flag if it successfully does something. I'm wondering if there's a more elegant way to go about it.
In the abstract, the problem can be phrased like this: given a complex object (with many levels of subobjects including arrays with circular references etc.), run it through a possible transformation then detect whether anything has changed. So the question is whether there is a simple way to detect changes in a complex object.
Watch.js provides ways to detect changes in an object, but only at top level, and will trigger if a field is changed even if it is subsequently returned to its original value.
Another approach would be to make a deep copy of the object and then deep compare with the original. However, from other questions here, deep copy looks like a nontrivial operation and deep compare has challenges of its own.
Is there an elegant trick I'm missing, or should I just stick to letting each optimization pass do its own bit of bookkeeping?
I would just post this as a comment, but I don't have the required rep.
I don't know if this would work in your situation, but what you could do is convert to JSON, then compare the strings:
JSON.stringify(firstObject) === JSON.stringify(secondObject)
Was looking around a bit more, and found another stackoverflow post with a similar question. There is a solution similar to mine, but what I found most interesting was the second solution, not chosen as the answer, I think it has what you need: Object comparison in JavaScript
I know enough jQuery/JavaScript to be dangerous. I have a JSON array that I'm interacting with using two different elements (a calendar and a table, to be precise). Is there an event handler (or any other way) I could bind to so that the table would refresh when the JSON changes?
Basic programming, parse the json (=string) into a javascript object or array. (you probably have already done that.) Use an implementation of the observer patern.
I suggest taking a good look at #Adam Merrifield 's interesting links.
Most of the time using getters and setter where you can fire a custom event (or call a callback method) inside a setter is the key in this.
KnockoutJS is a good framework to help you do such binding. It also uses the observable - observer/subscriber pattern.
using timers is not a really good idea.. little to much overhead. (doing stuff also when nothing gets changed. And you will always hop x ms behind (depending on the polling frequency).
You might want to consider Knockout.JS
It allows bi-directional mapping, so a change to your model should reflect on your view and vice/versa.
http://knockoutjs.com/documentation/json-data.html
However, it might be late stages of your dev cycle, but something to consider.
I've recently started using Backbone.js. I like the architecture, in terms of features it's almost exactly what I need...
... However I found the following caveats:
For Collections get means something different than for Models. There is no set. Attributes should be accessed in a regular way. I find it rather inconsistent. It's easy to confuse models and collections sometimes. Is there anything that can be done to overcome this?
Assigning initial values inside Model.extend doesn't always work. For example assigning url will not override the default behaviour. This can only be achieved through a call to set() method. Again very error prone.
I still don't know whether it's required to use get/set inside initialize() call.
I don't understand why I can't just call _.bindAll(this) inside initialize() and I have to list specific function names to be bound like this: _.bindAll(this, firstFunc, secondFunc, ...). This is not very DRY.
I would like to know: what are the best practices regarding the mentioned situations? What do you do to make the framework more consistent - any monkey patching? Am I doing anything wrong / against the convention?
I'd be grateful for any good real world examples. I did find this: http://documentcloud.github.com/backbone/docs/todos.html and http://liquidmedia.ca/blog/2011/01/backbone-js-part-1/ and those don't address any of the mentioned problems. In fact they just present the simplest ideas and absolutely no border cases, so anything more complicated could be useful.
EDIT:
Ok, and there is one more fundamental think I don't understand:
Am I ever allowed to place additional attributes on extension like this: var SomeModel = Backbone.Model.extend({ myattribute: myvalue }) ?
If so, then why don't subsequent calls to new SomeModel().get("myattribute") work ?
What exactly is this inside initialize() ? Is it model class or model instance ?
EDIT(2):
Well, I found this: http://maccman.github.com/spine/. It looks like Backbone.js 2.0, shares a similar name too :). Haven't tested it yet, which might be a bit of a show stopper, as the library is very recent. However from the docs side of things it looks very promissing. It gets rid of most of the problems that I found, it simplifies the API, it even gets rid of the dependency on underscore.js which for a library is a good thing. I'll post my further findings here.
Ok, I think I can say it quite confidently now: Backbone is dead, long live Spine.
Spine isn't exactly a fork of Backbone. It is however very similar and clearly inspired by some of the design decisions. It could be said that the author tried to retain as much as it was possible the original backbone API, getting rid of everything unnecessary or illogical. I find it also easier to extend. The list of changes includes among other things:
Getting rid of the dreaded Collections. "class methods" are used instead,
Getting most out of js prototypical nature (i.e. no get/set is needed). Attributes are accessed directly. An explicit call to save() is required in order to trigger an event.
Views and Controllers are now merged into new type of Controllers together whose purpose is to respond to DOM events and bind to model events.
The name :)
I find those design decisions coherent and sensible.
The reason there is no 'set' for Collections is because Collections are not arrays, they are sets, which are potentially ordered. The only supported way to place an element at a particular position is to add it to the collection and then sort the collection.
My team is debating the right name for a UI framework JavaScript method that ultimately does the following:
It gets the widgets state, if any
It removes the widget from the page
It returns the retrieved state so that the framework can recreate it
later
The initially proposed name was 'destroy.' Some team members feel that people may not expect a method named destroy to return anything. The name 'getStateAndDestroy' is more descriptive but suggests a single responsbility principle failure.
Thoughts? Do you see this as more of a naming or design issue?
git has something very similar, with the name stash.
What about 'stow'?
Makes me think of packing it away for possible later use.
Sounds like the element/widget is being cloned and removed, to be re-created at a later point, in the process.
What about: cloneAndRemove or backupAndDestroy hmmm they're pretty similar to what you've already got though.
How about 'takeAway' or 'takeOut' or 'grab'. Also reminds me a bit of the 'pop' method on a stack. I also think 'remove' is suitable for returning what you removed.