How to create an enums service in ember - javascript

I want to create a service of enums in ember so that I only have to inject it to use it everywhere. Is there a good way to do it?
Thanks.

Oh I found the solution.
I've doing the right thing but the ember serve is not that smart..
Steps:
just use: ember g service enums
and add an initializer with: ember g initializer enums
in newly created enums initializer, put
export default {
name: 'titleService',
initialize: function(application) {
application.inject('route', 'enums', 'service:enums');
}
};
restart the ember server and you get yourself an enums service

I think this would work also, in your service code you add Enumerable mixin
export default Ember.Service.extend(Ember.Enumerable, {
length: // ...
nextOjbect: // ..
next: // ...
value: // ...
}
According to the docs you will need to implement nextObject() and length. Ember service is just Ember object so I think this is much cleaner solution
http://emberjs.com/api/classes/Ember.Enumerable.html#toc_writing-your-own-enumerable
Let me know if this worked for you....

Related

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.

Configure Angular 2 HTTP service

I wonder what is the right way to use http service. For example all my requests to server starts with /Api.
Should I write this.http.get('/Api/SomeRoute/:id') every time, or more elegant way exists to omit Api?
Or should I create some other managerService which will use http?
Something like an endpoint url is probably a good example for a general configuration file.
In my angular 2 apps i use the dependency injection for it. In this case i have something like an app.config.ts using OpaqueToken to make it injectable:
import { OpaqueToken } from '#angular/core';
export interface IAppConfig {
appTitle: string;
endpointUrl: string;
};
export const CONFIG: IAppConfig = {
appTitle: 'MyApp',
endpointUrl: 'http://api.myrealservice.com/'
};
export const LOCALCONFIG: IAppConfig = {
appTitle: 'MyApp (LOCAL)',
endpointUrl: 'http://localhost:8080/api/'
};
export let APP_CONFIG = new OpaqueToken('app.config');
This way you can have several configs (for example for local development or production etc..) and define this as a provider in your module like this:
providers: [
...,
{
provide: APP_CONFIG,
useValue: CONFIG
},
...
]
Then i just inject this config wherever i may need it, for example in a backend service to use the endpointUrl:
...
constructor(#Inject(APP_CONFIG) private _config:Config) {
console.log(this._config.endpointUrl);
}
In your module you can just change the kind of Config you want to provide (in this example CONFIG or LOCALCONFIG for example) and don't have to change it anywhere else anymore.
Hope this helps.
After your edit, you added a second question Or should I create some other managerService which will use http?:
Short answer: yes. You should seperate logic of your components, services, etc. as much as possible.
Let's say you have a an API which serves information about cats and dogs. What you want to have in your frontend would probably be a CatService, a DogService and a BackendService or ApiService, whatever you want to call it.
The CatService and DogService are the ones your view components will interact with, for example they will have methods like getCatById() or something like that. These services will most likely interact with anohter service, the BackendService which will inject Http and use general methods like post(), get() and so on.
So your BackendService is the one who has to know the specific urls, handle the responses or errors and report back to the calling services with the results, while the other ones will just be used as a pipeline and handle specific business logic.
You are right, it is better to put repeating values in a variable. You can put the base URL in a const:
const apiUrl = '/Api/';
and then if there is a change to the URL, you only change it in one place, and also your code looks cleaner. The usage is like this:
this.http.get(apiUrl + 'SomeRoute/:id')
Of course you can also create a function that does that for you, but that may be too much abstraction.

Building Flux/React application without NodeJs EventEmitter

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
}
}

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

Ember.js Utility Class

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

Categories