Building Flux/React application without NodeJs EventEmitter - javascript

Hi I'm trying to build a Flux/React application with a go-lang back-end. I have been following a tutorial I found here. But I have a problem when building the store. In the tutorial something like this is used to create a base for the store.
var ProductStore = _.extend({}, EventEmitter.prototype, {...});
The problem I have is I do not have access to the EventEmitter library which I understand is a Nodejs lib? Is there an alternative I can use?

You can use NodeJS libraries in the browser! Take a look at browserify.
First some code:
// index.js
var EventEmitter = require("events").EventEmitter;
var ProductStore = function() {};
ProductStore.prototype = new EventEmitter;
Then you run browserify on it:
browserify index.js > bundle.js
Also worth a look is WebPack which does the same thing. (but has some additional features)

Well if you are using the flux implementation given by Facebook (https://github.com/facebook/flux), you can actually extends their FluxStore class which comes with a build in eventEmitter.
The only thing if you want to do that is you must use es6 classes (and use babel to transpile to es5).
The good thing about it is that you don't have to implement the addListener removeListener and emitChange methods, and that's very DRY :)
With this solution, your stores will end up looking like that :
var FluxStore = require("flux/utils").Store,
thing;
class ThingStore extends FluxStore {
getThing() {
return thing;
}
__onDispatch(payload) {
//your code
}
}

Related

Is it possible to use Node.JS based module from Java?

I was working on a React Native Native Module for Android. And it is written in Java (as what I researched from official docs and the internet). The problem is, I need to use a Node.JS based module to implement the functions that I want. Is there any possibility to use Node.JS module in Java?
The Node.JS module currently using a few Node native libraries such as fs and path. The code is 100% written using Node.JS.
Or is there any other way to create a React Native module without the use of Java?
The ultimate goal is to use this Node.JS based module to React Native App (without create a bridge between Node and React Native).
As I understand your question, your module doesn't have to communicate with native side. If it's that what you need, it will so easy to achieve. I'll make a simple example:
yourModule.js
export function a() {
// do sth
}
export function b() {
// do sth
}
export function c() {
// do sth
}
yourComponent.js
There is 2 ways to use your module:
1.
import { a, b } from '/path/yourModule'; // if you want to import some of the functions
class yourComponent {
function test() {
a(); // call function a from module
}
}
// Remember to check function's name if it's duplicated with other modules
2.
import * as module1 from '/path/yourModule';
class yourComponent {
function test() {
module1.a(); // call function a from module
}
}
// In this case, you won't have to worry about duplicated function's name, but you still
// have to check duplicated of the name of modules you have imported. For this example,
// the name module1 has been used.
P/s: you might get some error when using export/import incorrectly. So please investigate more about React Native export/import.

React Native imports not working after upgrade

Hi I've been in charge of an old React-Native iOS project and I need to upgrade its React-Native from 0.25.1 to 0.48.0 but I'm running into a lot of compiler issues and can't figure out how to update the code.
I have an index.ios.js file that looks like this:
var ReactNative = require('react-native');
var ResumeIns = require('./resume_ins_controller');
ReactNative.AppRegistry.registerComponent('ResumeInsController', () => ResumeIns.Navigation);
A resume_ins_controller.js in the root folder that looks like this:
var React = require('react');
var EntryManager = require('./entry_manager.js');
class ResumeInsNavigation extends React.Component {
//....
}
and an entry_manager.js in the root folder that looks like this:
class EntryManager {
//....
}
module.exports = EntryManager;
This code worked OK before the upgrade, but now I get this error:
Super expression must either be null or a function, not undefined
and the stack trace points to this line:
module.exports = EntryManager;
Does anyone know how to get this code working for React-Native 0.48?
There's been a ton of changes since 0.25.1. Knowing how painful updates can get, I'd suggest either:
In case of a very complex app: to update RN version by version with the help of release notes, and rn-diff if necessary.
In case of a fairly simple app: to start a new RN project from scratch, and move the app's logic over there.
Either way it would be a good idea to move to ES2015 imports for clarity on named vs default imports as the issue that you're describing is likely caused by the way things are imported, see v0.25.1 deprecations + a link to codemod that may help.
Good luck!

How to properly use es6 classes in different files by importing them in Meteor?

I have recently discovered Meteor and I am struggling with using ES6 classes and imports in a new Meteor project. What I want to do is to have a complex structure of classes, which methods get called from Meteor events/methods/helpers. I've added Babel.js to the project by writing a command $ meteor add grigio:babel and it works properly.
Example of what I am trying to achieve:
in server/models/article.js:
class Article {
static all() {
//returns all articles from db
}
}
in server/methods/articles.js:
Meteor.methods({
allArticles: {
Article.all();
}
})
Having just that raises ReferenceError: Article is not defined in a methods file, which is adequate. So I have got three options: write all classes in one file, append all classes to a global object or use a good module system like Browserify. Obviously, third option is better.
But how do I use that? Babel converts export, import into Browserify by default and Meteor raises a require is not defined error on page refresh. After googling the problem I didn't find a clear solution on how to add Browserify to Meteor. Should I add a npm packages support to Meteor, add a npm package of browserify and add it manually to Meteor on every page where I import/export anything? Or should I use a completely different approach? How is this task usually handled in Meteor? Thank you!
I was reading about this earlier and found this issue on github that may help.
Essentially just assign the class to a variable that is exposed to both the client and server (lib/both/etc depends on your file structure). Like so:
Article = class Article {...}
Seems to be the best solution at the moment.
The way I do this is to collect objects together into various namespaces, for example:
// Global
Collections = {};
class Article {
static all() {
//returns all articles from db
}
}
_.extend(Collections, { Article });
Then to avoid having to use Collections.Article everywhere I can use the following in the file I need to access Article in:
// Make `Article` available
let { Article } = Collections;
I am using Meteor 1.4.1.1 and the error remains, when reproducing your approach. However, there are some new ways to use es6 classes now:
1. Export your class as a constant (e.g. for use as a singleton object):
class MyModuleInternalClassName {
//... class internals
}
export const PublicClassName = new MyModuleInternalClassName();
You can import this one via
import {PublicClassName} from 'path/to/PublicClassFileName.js';
2. Export your class directly as the module's default
export default class PublicClassName {
//... class internals
}
and then import it (as with the above one) as the following
import {PublicClassName} from from 'path/to/PublicClassFileName.js';
let myInstance = new PublicClassName();
+++++++++++++++++++++++++++++++++
Regarding the question of OP and the error, you can try something like this:
Article.js
class InternalArticle {
constructor(){
//setup class
}
all() {
//returns all articles from db
}
register(article){
//add article to db
}
}
export const Article = new InternalArticle();
Import and use the Singleton
import {Article} from 'path/to/Article.js';
//either register some article
Article.register(someArticle);
//or get all your articles
const allArticles = Article.all();

Common js modules in react native

Is it possible to make use of common js modules with react-native? The use case is sharing logic between a mobile and web version of a react project.
Ok, I'm new to this too but I think I've figured out how to include js code. I didn't have to add anything to the standard react native installation.
Create a Library of code:
//library.js
exports.foo = function() {
//Do stuff here
return "Here";
}
Import into another js file:
var lib = require("./library.js");
var myString = lib.foo();
I found the info from this blog post:
http://0fps.net/2013/01/22/commonjs-why-and-how/

Unit testing on "react + react-route" stack

I've read many recommendations of how it's possible to render routed via react-router components, but I still can't to make it work. I tried to find it using github codebase search, still no luck. And at this point all I need is one working example.
Here is my boilerplate project, but maybe it's not important. I just want to see some react-route unit-testing working example.
I got mine working after I found the super-secret hidden react-router testing guide.
Instead of using Object.assign to create a router stub, I used sinon.js so I could create better stub functions that return the appropriate values for my tests.
EDIT: Went back to look again at your boilerplate and saw that your stub router is borrowed from the same example. Sorry. So where exactly did you get stuck?
EDIT-AGAIN: I'm not using Jest, so here are the other pieces that I needed to solve the testing puzzle:
If you're using browserify, and want to test in plain mocha (without having to build), you'll need to hack require to compile your jsx for you:
var fs = require("fs");
var reactTools = require("react-tools");
require.extensions[".jsx"] = function(module, filename) {
var jsxContent = fs.readFileSync(filename).toString();
var jsContent = reactTools.transform(jsxContent);
return module._compile(jsContent, filename);
};
You need a fake DOM. JSDOM is just plain terrible. I got it working using domino instead.
var domino = require("domino");
global.window = domino.createWindow();
global.document = global.window.document;
//Set the NODE_ENV so we can call `render`.
//Otherwise we get an error from react about server rendering. :(
process.env.NODE_ENV = "test";
Then you can require your components in through the stub-router, and render your components into DOM nodes using React.render():
var MyComponent = fakeRouter(require("./MyComponent.jsx"));
var component = React.render(
< MyComponent / > ,
document.body
);
node = component.getDOMNode();
//I used `zepto-node` and `chai-jq` to assert against my components
The (possbily new in v4) way of doing this is to wrap the component you're testing in the MemoryRouter provided by react-router.
import {MemoryRouter} from 'react-router-dom';
import {render} from 'react-dom';
render(<MemoryRouter>
<YourComponent>
</MemoryRouter>, node, () => {});

Categories