I'm still getting acclimated to flow, but here is a case I'm a little confused as to how to handle.
I have a few classes that are fired, their "fireScript" method, in a method for a promise.all. I do not know how I would annotate a class as it moves thru a map.
import ShoeClass from 'products/ShoeClass';
import HatClass from 'products/HatClass';
//somewhere else the code
await promise.all([ShoeClass, HatClass]
.map(product => product.firScript()))
this is giving me errors, so I am trying to find a generic flow type for a Class, is that even possible?
.map(product <---- this wants an annotation. Each mapped class is different obviously, but how would I annotate it? With a generic?
You may try:
await promise.all(
[ShoeClass, HatClass].map((product: Class<*>):Promises<*> => product.firScript()));
There is a cool flowType cheat sheet here for quick reference.
Related
I'm reading NgRx's basic Architecture tutorial, and they explain about Actions:
The interface has a single property, the type, represented as a string. The type property is for describing the action that will be dispatched in your application. The value of the type comes in the form of [Source] Event and is used to provide a context of what category of action it is, and where an action was dispatched from.
https://ngrx.io/guide/store/actions
I'm wondering about the rationale or benefit of not enforcing this kind of arbitrary string format? Why not have Actions enforce you defining both a source and event property that can be composed by the library into a type attribute? It seems like it leaves room for error, making it easy to ignore the recommended format. Is there any advantage to this?
It's just a convention. Strings can be used as types, so it's "safe" from that perspective. At some point, the onus has to be on the developer to choose meaningful strings, right?
I tend to do this to keep things consistent for each suite of actions:
import { createAction, props } from '#ngrx/store';
import { Config } from '../models/config.model';
const appAction = '[App]';
export const getConfig = createAction(
`${appAction} Get Config`
);
export const setConfig = createAction(
`${appAction} Set Config`,
props<{ config: Config }>()
);
Here is a tangentially related article about actions and action creators. Interesting read, but doesn't truly answer your question.
I'm working on a Symfony application and just got SSR for JS working using https://github.com/spatie/server-side-rendering. So far I only worked with "readymade" SSR solutions for React, but currently I'm trying to use hyperHTML/viperHTML and am facing a few issues that so far I wasn't able to solve by looking at the available docs/examples.
My current test snippet is this:
const viperHTML = require('viperhtml');
class Component extends viperHTML.Component {
constructor(props) {
super();
this.props = props;
}
render() {
return this.html`
<h1>Hello, ${this.props.name}</h1>`;
}
}
console.log(new Component({ name: 'Joe' }).render().toString());
The thing here is that without explicitly calling render() I get no output. Looking at some of the official examples this shouldn't be necessary, at least not with Component. I already tried using setState() in the constructor, for example, but no difference.
Also, without using both, console.log() and toString(), I get no output either. Which is unexpected. I get that toString() might be necessary here (without it a <buffer /> is being rendered), but the console.log() seems odd. This might not be related to viperHTML at all of course. But instantiating the component is the only thing I expected to be necessary.
It's also not clear to me yet how I can write an isomorphic/universal component, i.e. one file which has the markup, event handlers etc., gets rendered on the server and then hydrated on the client. When I add an inline event handler as per the docs (https://viperhtml.js.org/hyperhtml/documentation/#essentials-6) it actually gets inlined into the rendered markup, which is not what I want.
I checked hypermorphic and the viperNews app, but that didn't really help me so far.
In case it helps, you can read viperHTML tests to see how components can be used.
The thing here is that without explicitly calling render() I get no output.
Components are meant to be used to render layout, either on the server or on the client side. This means if you pass a component instance to a hyper/viperHTML view, you don't have to worry about calling anything, it's done for you.
const {bind, Component} = require('viperhtml');
class Hello extends Component {
constructor(props) {
super().props = props;
}
render() {
return this.html`<h1>Hello, ${this.props.name}</h1>`;
}
}
console.log(
// you need a hyper/viperHTML literal to render components
bind({any:'ref'})`${Hello.for({ name: 'Joe' })}`
// by default you have a buffer to stream in NodeJS
// if you want a string you need to use toString()
.toString()
);
Since NodeJS by default streams buffers, any layout produced by viperHTML will be buffers and, as such, can be streamed while it's composed (i.e. with Promises as interpolation values).
It's also not clear to me yet how I can write an isomorphic/universal component, i.e. one file which has the markup, event handlers etc., gets rendered on the server and then hydrated on the client.
The original version of hyperHTML had a method called adopt() which purpose was to hydrate live nodes through same template literals.
While viperHTML has an viperhtml.adoptable = true switch to render adoptable content, hyperHTML adopt feature is still not quite there yet so that, for the time being, you can easily share views between SSR and the FE, but you need to either take over on the client once the SSR page has landed or react, for the very first time, differently and take over on the client at distance.
This is not optimal, but I'm afraid the hydration bit, done right, is time consuming and I haven't found such time to finalize it and ship it.
That might be hyperHTML v3 at this point.
I hope this answer helped understanding how viperHTML works and what's the current status.
Hi guys I add this error and I don't understand why... I'm using the starter project of react-native-firebase, and I'm trying to use firestore
Although there might be an issue with the library which needs investigating, your code is generally wrong. State in a React component should be data which when changed, causes a re-render. You do not need to assign your collection to state, this can be done as a class property. Also, using a constructor & componentWillMount is wrong as they're essentially the same thing - I don't know enough how it'd handle both cases internally though.
Your code would better work like so:
constructor() {
super();
this.ref = firebase.firestore().collection('users');
}
componentDidMount() {
this.ref.add({ name: 'moo' });
}
I have got same error. Please create the collection with the name 'users' and add a dummy document. Then try.
I'm new to redux and looked at redux-actions or using switch statements in reducer, and though I'm not against using a switch statement, I'm wondering, isn't it easier to just use the call the action method?
Here's what I'm thinking
import actions from './actions'
const reducer = (state = {}, action) => {
if (actions[action.type]) return Object.assign({},
state, actions[action.type](action)
);
return state;
}
I've just tested this on my first reducer and action, and it works, but it seems quite obvious so I'm wondering why the switch type is the chosen way?
Switch statements are certainly the most common approach, but lookup tables are common as well. You can even use plain if/then conditions if you want. Ultimately, how you write your reducers is up to you.
FYI, this topic is covered in the Redux FAQ, in the FAQ: Reducers section. You might also want to read the new "Structuring Reducers" how-to section as well.
Some observations:
Don't refer to these external functions as "actions". They're not actions. They're actually reducers themselves.
Being reducers, you really ought to be passing the state object to them. Oftentimes, you'll want/need to utilise information contained in the current state, as well as information contained in the action object.
Otherwise, this seems like an appropriate approach.
I am kind of confused about which methods belong with and when to use them.
Right now, I am using subscribe for basically everything and it is not working for me when I want a quick static value out of Firebase. Can you explain when I should use subscribe vs other methods other than for a strict observable?
When working with async values you have a few options: promises, rxjs, callbacks. Every option has its own drawbacks.
When you want to retrieve a single async value it is tempting to use promises for their simplicity (.then(myVal => {})). But this does not give you access to things like timeouts/throttling/retry behaviour etc. Rx streams, even for single values do give you these options.
So my recommendation would be, even if you want to have a single value, to use Observables. There is no async option for 'a quick static value out of a remote database'.
If you do not want to use the .subscribe() method there are other options which let you activate your subscription like .toPromise() which might be easier for retrieving a single value using Rx.
const getMyObjPromise = $firebase.get(myObjId)
.timeout(5000)
.retry(3)
.toPromise()
getMyObjPromise.then(obj => console.log('got my object'));
My guess is, that you have a subscribe method that contains a bunch of logic like it was a ’.then’ and you save the result to some local variable.
First: try to avoid any logic inside the subscription-method -> use stream-operators before that and then subscribe just to retrieve the data.
You much more flexible with that and it is much easier to unit-test those single parts of your stream than to test a whole component in itself.
Second: try to avoid using a manual subscriptions at all - in angular controllers they are prone to cause memory leaks if not unsubscribed.
Use the async-pipe instead in your template and let angular manage the subscription itself.