Ember.js Utility Class - javascript

I am new to Ember.js and Javascript in general. I am using ember-cli to create an app that could use a DateUtil class to perform some date manipulation. I noticed that ember-cli has a utilities generator to produce the following boilerplate code in app/utils/date-util.js:
export default function dateUtil() {};
I am wondering how to write a utility so that I can use it across my application. Specifically, as an example, in a controller:
export default Ember.ObjectController.extend({
startDate: dateUtil.thisMonday()
});
where thisMonday() would return the date of this Monday using moment.js like:
moment({hour:0}).day(1);
There would be many others similar to thisMonday() as part of dateUtil.

You simply need to import the ES6 module that exports your utility function, in each of the controllers that want to use it, like so:
import dateUtil from 'app/utils/date-util';
export default Ember.ObjectController.extend({
startDate: dateUtil().thisMonday()
});
Note that the path is not necessarily app/utils/... though, you must replace app with the name of the app that you used when initially generating the app. You can verify what this is by looking in app/app.js, and looking for the value of modulePrefix within Ember.Application.extend().

Just import your class using the ES6 module syntax.
import dateUtil from 'app/utils/date-util.js';
References:
ES6 modules
ember-cli guide on modules

Related

Memory when importing js objects in react

I am new to react and its transpiled way of generating javascript.
In react side, I have a class Utility that uses a data object UserData organized as below -
UserDataObj.js
class UserData{
this.someobj = {};
//some function here
something(){
}
}
const UserDataObj = new UserData();
export {UserDataObj};
Utility.js
import {UserDataObj} from './data/UserDataObj';
class Utility {
doSomething(){
//UserDataObj.something();
}
}
const utility = new Utility();
export {utility};
I have another ReactApp UserApp.js, that also uses UserDataObj and Utility (although not good design wise) -
import {UserDataObj} from './data/UserDataObj';
import {utility} from './Utility';
class UserApp extends React.Component{
//does something with UserDataObj
// also does somethign with utility
}
My question is, how many utility and UserDataObj instances will be created in memory, when UserApp is rendered. My guess is, it should be only 1 instance for both. But I want to confirm if importing n times creates a new instance every time.
Any good read on this topic is greatly appreciated.
Thanks
This depends on the bundling tool, and not React. I imagine that the new browser ES Module resolution scheme works in the same way.
Most bundlers that I know of, and other import schemes such as Node.js' require module resolution will cache the import between files and always return the same exported objetcs. This is a requirement for prototype inheritance, for example, otherwise, it would mess up the instanceof operator.
That exported new Utility() instance will be the same for any module that imports it. In order to generate new instances, you would have to have a function.

Why capitalize React here? import * as React from 'react'

Most examples I see of importing modules use lowercase; e.g.
import * as tools from './tools';
The rule I usually see is, if it's a constructor function then use PascalCase; otherwise use camelCase.
However I always see import * as React from 'react' even though React is not a constructor function (can't do new React()). Why is it always capitalized, and when from a JavaScript style standpoint would I choose to capitalize a library or module like './tools'?
Most of my background is in C# and C++ so I'm inclined to capitalize libraries (import DateFns from 'date-fns', import * as Tools from './Tools').
Because it is a namespace and I guess because it is a framework brand. Brands that are frameworks tend to get capitalized more often (Vue, Backbone, Ember, etc).
When using Typescript as your javascript super-set it makes a whole lot of sense to capitalize your namespaces, since it has a C# like flavor to it.
But even with new ECMAScript versions there is a benefit to capitalize namespaces. I think it keeps things more readable.
I just stumbled on this older question.
The primary reason why the 'react' module needs to be imported as React (exact spelling and capitalization) is so that JSX works properly.
From the JSX In Depth doc:
Fundamentally, JSX just provides syntactic sugar for the React.createElement(component, props, ...children) function.
...and later:
React Must Be in Scope
Since JSX compiles into calls to React.createElement, the React library must also always be in scope from your JSX code.
Example
This component in JSX:
const SimpleComponent = () => (<div>simple component</div>);
...gets compiled into this:
var SimpleComponent = function SimpleComponent() {
return React.createElement("div", null, "simple component");
};
...so React must exist in the scope or the compiled code will throw this error when it runs:
ReferenceError: React is not defined

Service inheritance with Angular 1.x and ES6

I am using Angular 1.6 with ES6. Until now I implemented inheritence with the extend keyword on ES6 classes
export default class myChildService extends myBaseService {
constructor(someDependency){
'ngInject'
super();
someDependency.doStuff();
}
}
and registered the child-class as angular-service
import myChildService from ./myChildService
angular.module('myApp', [])
.service('myChildService', myChildService)
This works well so far!
However I would like to split my application into smaller modules. This means I will have several different angular-modules which will need access to myBaseService in order to inherit the functionality.
I could just import the file containing myBaseService, but this seems not very angulary. It basically means I disregard angular-modules and DI everytime I use inheritance.
Question:
Is there any way to export an ES6-class from an angular-module base so that I can reuse it on an angular-module child which depends on base?
Maybe I am just looking at this the wrong way - if you have other suggestions to implement inheritance of angular-services/ factories using ES6-classes, please go ahead.
Why importing is not angulary? If you would like to use base service functionality, the module should know it's definition.

How to rewrite this require module with import module syntax

I'm new to JavaScript and trying to import this module using ES6. It's currently written as:
var neo4j = require('neo4j-driver').v1;
I have:
import neo4j from 'neo4j-driver;'
But I have no idea how to handle the .v1?
Reference: http://neo4j.com/developer/language-guides/
Thank you.
Since v1 is a member of the module, you can use import's member syntaxes.
Including { member as alias }:
import { v1 as neo4j } from 'neo4j-driver';
You can use javascript destructuring and do import { v1 as neo4j } from 'neo4j-driver' which can then be used in your code like neo4j.someMethod() or whatever (I'm not familiar with the library in question).
See here for reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

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();

Categories