Where to define record methods in a Redux app - redux

I am building an app with React + Redux + Immutable JS and am running into some architectural problems. To illustrate I will use my user record as an example. The user object is an Immutable Record, defined in the user reducer. Now I would like to define some methods for this user (for example, isCurrentUser(userId), which would return a boolean and can be called on any user instance). From what I gather, the state should simply be plain objects though (reference: How to put methods onto the objects in Redux state?)
However, since this method wouldn't change the state of the application it doesn't make sense to use the typical Redux flow either. Is it acceptable for me to define methods within my Immutable Records, or should I be defining some helper methods in a separate JS file. Or maybe there's something else I haven't thought of?

You can create a new layer called 'services' and put this methods inside it. So, you can have a services/UserSession that is used like.:
{ isCurrentUser } from './services/UserSession'
isCurrentUser(user)
Does it help you?

Related

Why are property accessor methods different for Immutable Maps and Records?

I am using Immutable JS in conjunction with React + Redux. For the most part I really love how it reinforces the Redux paradigm, with the exception of its property accessor methods.
For Immutable Maps, one must access properties using the Immutable get method.
Ex. this.props.exampleMap.get('mapProperty');
However, for Immutable Records, there is no get method. Instead you just access properties with the dot method as with normal JS objects.
Ex. this.props.exampleRecord.recordProperty
My question is, why is there this discrepancy? This is making me a little OCD because my components are now filled with a mix of both methods and frankly it's a little ugly.
You actually can use .get(...) for immutable records. The way I think of is that records have additional nicer syntax by allowing you to access the properties directly.
If you take a look at the type definitions of a record, you'll see that record constructors create objects with types Immutable.Map<string, any>.
This nicer syntax is possible because you predefine the properties of the record upon creation.
Here is the immutable record creation example taken directly from their docs
const { Record } = require('immutable')
const ABRecord = Record({ a: 1, b: 2 })
const myRecord = new ABRecord({ b: 3 })
So remember, you give the Record function an object with default values and it returns a constructor you can use to create object with new.

In Meteor.js, what's the difference between method-based database API design and the subclass approach?

Namely, what are the advantages and disadvantages of the following approaches to building a server-side database API in Meteor?
Method-based
import Db from 'Db';
Meteor.method({"insert": (data) => {Db.insert(data)});
Subclass-based
import {Mongo} from "meteor/mongo";
class MyCollcetion extends Mongo.Collection {
insert: (data) => {super.insert(data);}
}
This problem has been solved below; there is a similar question for further reading: Meteor method vs. deny/allow rules
This is mainly a matter of ease vs control. Subclassing may be easier for simple things, and methods are more powerful.
This can also be affected by your state of mind (or affect it): CRUD vs. action-based mutation.
insert/update/remove go well with a CRUD state-of-mind, while you can associate methods with action-centric RPC mutators.
Eventually, this is a matter of personal preference, so I will try to give a short factual description and let the readers to decide based on their taste.
Subclassing
By default, Meteor automatically generates mutation methods (insert, update, remove) when a collection is instantiated.
Those methods are called behind the scenes when calling MyCollection.insert(mutator, cb) on the client side (outside client-side method code). When arriving to the server, the data are first passed through allow/deny rules and then executed.
When subclassing, you override those methods and get a 'hook' into the process.
Using methods
When defining a Meteor method you get full control of the process.
You set the parameters and the name of the method and you can perform the validation and authorization as you wish.
You can also create a method stub for client-side use, which generates optimistic UI until the results of the method server execution are received.
You can use something like a validatedMethod to get some extra validation logic and modularity to your method.
You can also prevent the creation of the default mutation methods by setting a false value for the defineMutationMethods option when instantiating the collection. You can also forbid direct mutation from the client by supplying the appropriate deny rules.
While subclassing allows you to use MyCollection.insert(...), etc. on the client, you need to call the method name with the arguments that you defined in order to mutate data.

Meteor: Call template helper from other template

I have two templates and I've defined JavaScript helpers and events to go with each. When a button is clicked in template A, one of the things I want to do is call a helper function for template B which will change what's displayed on the screen. Is this possible?
If it's not possible, I'd instead like to reload template B.
How can I do either of these? Do I use Tracker.autorun? Reactive variables? Ideally I would do, inside an event function for template A,
B.helpers.call("helperFunctionFromTemplateB");
There are a lot of solutions to what I think you want to achieve, but the answer really depends on context.
If template A is a child template of B:
You can pass a reference to a ReactiveVar in the parent template down to the child template's data context and modify it using {{>childTemplate reactiveVar=reactiveVar}} where reactiveVar is a helper in the parent template that returns the reference to the reactive variable
If the thing you want to change is in the parent's data context, you can use Template.parentData(n) where nis the amount of levels you want to jump up. While modifying the parent's data may not immediately seem reactive, you can make the data prop reactive by accessing it via Template.currentData()
Use some kind of globally accessible state. The most common answer would probably be to use the Session package and use Session.get('var') and Session.set('var', val).
Use an event emitter. This approach gets +'s for decoupling and reusability, but it's also potentially heavy handed if you only need to modify this variable in one place from one source (i.e. your requirements are simple)
Meteor 1.3 - If you want to make references to your reactive data in multiple places but don't want to create a global like Session, use a ReactiveVar or Reactive Dict (closer to session), create your variable where it makes sense, export it, and import it in your templates/anywhere else to be used.
There's a lot of other solutions, these are just the first that come to mind. If you provide more specific context, I'll provide a code sample of what I think's best and explain why. :)

Passing value between two components in angular2-meteor project

I am using angular2-meteor.
When I try to pass a value between two components (when the value change in the first component, create an event in second component and use this new value), I have two ways right now:
One way is meteor way: using this.autorun and Session.get.
Another way is angular2 way: using Injectable service with EventEmitter.
Which way should be prior? Or is there any other better way? Thanks
Now I used angular2-meteor a while.
Although the angular2-meteor tutorial has no example so far about using or choosing Angular 2 service or Meteor Session.
But I feel angular 2 takes the lead in the front end, while meteor makes reactivity easier and also handle all back end things.
So I went with angular2 way using service to share between components. And service is very powerful like #todd-w-crone said.
If anyone has better answer, I will switch to accept that one.
I find it practical to create a new service called App.states.ts which is accessed globally and mimics Session (get / set).
I commonly import this service to all necessary components to get or set new value such as User.status, company.profile, lastProduct, etc.
Since this service is #injectable it can also make use of other services, in case a value hasn't been set already.
This allows me to ask for a variable in a component appState.getLastModifiedItem(), then in app.states.ts I'll write this function to pass this.modifiedItem or either:
Request another service item.service.ts to fetch data
Call another function with itemCollection.findOne({...}) and return such value.
You can configure Mongo queries as you want and either store static data in appState or keep subscription items in appState.
Do take into consideration that all subscriptions handled by an #injectable within a component are imported by such component. Be wary of conflicting subscriptions between components/services.

Calling a getter without assigning it to anything (lazy loading)

I have a DTO which can be fully loaded or lazy loaded using Lazy Load Pattern. How it is loaded depends on what the Flex Application needs. However, this DTO will be sent to a Flex application (swf). Normally, a collection for instance, will only be loaded when called. In my case however, the collection will only be called in Flex, so my implementation on the .NET side will obviously not work in this case (except if Flex would do a server call... something I would like to avoid).
In the getter of the collection, the data is retrieved from the database. If I would be working with ASP.NET pages, it would work, but not if the DTO is sent to Flex.
How would you deal with this? I could call the getter before sending the DTO to Flex, but that seems awful... + calling the getter can only be done if it is assigned to something (and the local variable that will hold the collection will never be used...).
You can introduce a method to load dependents - loadDependencies - that should take of all lazy loading for your DTO object before being sent over the wire (to Flex). You can abstract this method to an interface to streamline such process across different DTOs. There is nothing against using getters the way you described it inside this method.
I would probably introduce a Finalize method for the class and perhaps a FinalizeAll extension method for various collections of the class. This method would simply go through and reference all the getters on the public properties of the class to ensure that they are loaded. You would invoke Finalize (or FinalizeAll) before sending the object(s) to your Flex app. You might even want to make this an interface so that you can test for the need for finalization before transfering your objects and invoke the method based on a test for the interface rather than checking for each class individually.
NOTE: Finalize is just the first name that popped into mind. There may be (probably is) a better name for this.

Resources