How to fetch data from Mirage in Ember.js? - javascript

I need to return a list of users from Mirage. I need this list for rendering it on the front end. How do I do this?

To install mirage:
ember install ember-cli-mirage
Once this is done, you need to configure Mirage to send data. This can be done by updating the file mirage/config.js.
In the mirage/config.js file, its better you define a namespace so that Ember application's call does not conflict with the routes defined already.
Say you want Mirage to return a sample list of users. You can do something like this in the mirage/config.js file:
export default function() {
this.namespace = '/api';
this.get('/users', function() {
return {
// list of users
};
});
}
Now whenever the Ember application makes a get request to /api/users , a list of users is returned.
Only doing this isn't enough, you need to make your application to default making requests to the namespace /api.
This is done by creating an application adapter.
To create an application adapter:
ember generate adapter application
Then in app/adapters/application.js, add the namespace like this:
export default DS.JSONAPIAdapter.extend({
namespace: 'api'
});
Restarting the Ember server would include Mirage in your build.
Say you were making a request for all users in the model function of a route:
export default Ember.Route.extend({
model() {
return this.get('store').findAll('users');
}
})
Here, when you request for all the users, Ember data will fetch all users from /api/users.

Related

Meteor 1.4, how to access a user defined collection in a package

Background:
So I'm creating an admin package for meteor 1.4.2 with react so I can learn how to do that sort of thing. The admin package will just be able to update user defined collections (insert, delete, modify).
I have this file in my application under imports/api/posts.js:
// imports/api/posts.js
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
export const Posts = new Mongo.Collection('posts');
if (Meteor.isServer) {
Meteor.publish('posts', function postsPublication() {
return Posts.find();
});
}
I can easily access this file within my application using for example import { Posts } from '../imports/api/posts.js';.
Problem:
How can I access the same Posts collection from within the admin package so I can insert a new item, remove one, etc?
Also, I saw this post earlier about a similar thing, but does that mean packages such as yogiben:admin don't work with the module system either?
The key to understanding this is realising that some meteor packages are libraries, and some are extensions of the (Meteor) framework as defined here.
yogiben:admin is an extension of the Meteor framework, in that it needs to be able to find code that you have written (your collections) in order to work correctly.
How you enable this is up to you. Previously collections were globally defined, so that they would be (automatically/eagerly) imported, and generally outside the /client or /server directories so they would be accessible on both the client and server.
Now you have the choice - define your collections outside the /imports directory, and they will still be eagerly imported, or import them where your admin framework requires them. As a third way you could require they be attached to the (server side) global object e.g. as a dict (i.e. global.myCollections = {'posts': Posts}), and (in browser) the window object (with window.myCollections = {'posts': Posts}).
yogiben:admin's example starter repo keeps everything outside /imports, however I suspect this would still work fine if you just kept the collection definitions outside /imports, moving the rest of the code to the currently recommended project structure.
I do not think that Meteor has a way to get all collections defined in an app internally.
To achieve that you could override the Mongo.Collection method to keep a reference to every created collections.
const _oldCollection = Mongo.Collection;
Mongo.Collection = function(name, options) {
const c = new _oldCollection(name, options);
Meteor.myCollections[name] = c;
return c;
};
Then use it as:
// define new collection
new Mongo.Collection('questions');
// retrieve collection
const c = Meteor.myCollections['questions'];
Make sure the code used to override Mongo.Collection loaded before you use it to define new collections.

How to include external JavaScript libraries in Angular 2?

I am trying to include an external JS library in my Angular 2 app and trying to make all the methods in that JS file as a service in Angular 2 app.
For eg: lets say my JS file contains.
var hello = {
helloworld : function(){
console.log('helloworld');
},
gmorning : function(){
console.log('good morning');
}
}
So I am trying to use this JS file and reuse all the methods in this object and add it to a service, so that my service has public methods, which in turn calls this JS methods. I am trying to reuse the code, without reimplementing all the methods in my typescript based Angular 2 app. I am dependent on an external library, which I cant modify.
Please help, thank you in advance.
With ES6, you could export your variable:
export var hello = {
(...)
};
and import it like this into another module:
import {hello} from './hello-module';
assuming that the first module is located into the hello-module.js file and in the same folder than the second one. It's not necessary to have them in the same folder (you can do something like that: import {hello} from '../folder/hello-module';). What is important is that the folder is correctly handled by SystemJS (for example with the configuration in the packages block).
When using external libs which are loaded into the browser externally (e.g. by the index.html) you just need to say your services/component that it is defined via "declare" and then just use it. For example I recently used socket.io in my angular2 component:
import { Component, Input, Observable, AfterContentInit } from angular2/angular2';
import { Http } from 'angular2/http';
//needed to use socket.io! io is globally known by the browser!
declare var io:any;
#Component({
selector: 'my-weather-cmp',
template: `...`
})
export class WeatherComp implements AfterContentInit{
//the socket.io connection
public weather:any;
//the temperature stream as Observable
public temperature:Observable<number>;
//#Input() isn't set yet
constructor(public http: Http) {
const BASE_URL = 'ws://'+location.hostname+':'+location.port;
this.weather = io(BASE_URL+'/weather');
//log any messages from the message event of socket.io
this.weather.on('message', (data:any) =>{
console.log(data);
});
}
//#Input() is set now!
ngAfterContentInit():void {
//add Observable
this.temperature = Observable.fromEvent(this.weather, this.city);
}
}

How to pass in data from Node JS Express with Ember-Ajax?

I'm working on an Ember website with a Node JS Express API. I'm using ember-ajax to connect to the API.
EDIT:
Ember version is 1.13
Ember Data : 1.13.15
The problem is Ember does the AJAX call as if it was directed towards localhost:4200 (Ember) when it should be sent towards localhost:9029 (Express). Of course, this throws a 404.
How do I make it so it sends the request to the API instead of itself? I've tried --pxy after ember s but that does not work. It seems like it's ignoring the files I created. I'm very new to Ember.
app/services/ajax.js
import Ember from 'ember';
import AjaxService from 'ember-ajax/services/ajax';
export default AjaxService.extend({
namespace: '/api',
host: 'http://localhost:9029',
trustedHosts: [
'http://localhost:9029',
]
});
app/routes/test.js
import Ember from 'ember';
import AjaxService from 'ember-ajax/services/ajax';
export default Ember.Route.extend({
ajax: Ember.inject.service(),
model() {
return this.get('ajax').request('/gimmieDatDate', {method: 'POST'});
}
});
Could you write out the full command you used to run the server? Something like
ember s --proxy http://localhost:9029
should work.
You should specify the host in your (application) adapter.
// app/adapters/application.js
export default DS.JSONAPIAdapter.extend({
host: 'https://api.example.com'
});
Docs: https://guides.emberjs.com/v2.4.0/models/customizing-adapters/#toc_host-customization

Ember: Access ember data 'store' object from utility class

I have a utility class for validating usernames in my ember application and have it setup as specified in the ember-cli docs. I do client-side username validation in several places in my application (components and controllers) so I wanted to pull the validation logic out into a reusable method.
The file is at /app/utils/username-validator.js and I can successfully include the file in my app by importing it like so: import usernameValidator from 'my-app/utils/username-validator';
This works great so far and I've used the pattern for several utility classes. The problem I'm running into now is that I'd like the username-validator method to include a check to see if the username already exists.
As I am using Ember-Data I'd like to check the Ember-Data store. By default, the store appears to only be accessible in controllers and routes. How can I make it accessible in my utility class? All the injection examples I've seen deal with injecting the store into other first class Ember objects like components.
Is it possible to inject the store into a simple utility class as well?
Thank you!
I am using the following versions:
Ember-cli v0.2.6
ember.debug.js:4888 DEBUG: -------------------------------
ember.debug.js:4888 DEBUG: Ember : 1.12.0
ember.debug.js:4888 DEBUG: Ember Data : 1.0.0-beta.18
ember.debug.js:4888 DEBUG: jQuery : 1.11.3
ember.debug.js:4888 DEBUG: Ember Simple Auth : 0.8.0-beta.2
ember.debug.js:4888 DEBUG: -------------------------------
===== Updated with detailed solution based on answer from torazaburo ======
Creating a service works great. Here is how I did it using ember-cli (v0.2.6) and ember v1.12.0
Create your service inside of /app/services/<service-name>.js
The service blueprint will look like this (note the name of the service is based on the name of the file):
import Ember from "ember";
export default Ember.Service.extend({
myFunction: function(){
}
});
Create an initializer for your service in /app/initializers/<service-name>.js which is used to inject your service into the different top level Ember objects (such as routes, controllers, components etc). Note that the file name of the initializer should match the file name of your service.
The blueprint for the initializer will look like this:
export function initialize (container, app) {
// Your code here
}
export default {
name: '<service-name>',
initialize: initialize
};
To give a concrete example, lets say your service is called validator and contains a bunch of validation routines. You want to inject the validator into all controllers, and you also want to inject the Ember Data store into the validator itself. You can do it like this:
export function initialize (container, app) {
// Inject the Ember Data Store into our validator service
app.inject('service:validator', 'store', 'store:main');
// Inject the validator into all controllers and routes
app.inject('controller', 'validator', 'service:validator');
app.inject('route', 'validator', 'service:validator');
}
export default {
name: 'validator',
initialize: initialize
};
Make your utility into a "service", into which you can inject the store. Actually, it sounds like your utility should be a service anyway, even if it doesn't need the store. By making it a service, for instance, it becomes much easier to stub it out when writing tests. With a service, you need neither import anything nor do any global injections in initializers, you can simply say
export default Ember.Component.extend({
myService: Ember.inject.service(), // inject services/my-service.js
foo: function() {
this.get('myService').api1(...);
}
});

dependency injection without singleton in ember-cli

Just converted my app to ember-cli, but I don't know how to use Ember.Application.register any more because register doesn't seem to be available when Application is started with extend rather than create.
import Ember from 'ember';
import App from 'myapp/app';
var AdminMyController = Ember.ObjectController.extend({
});
// THROWS ERROR HERE BECAUSE register isn't, uh...registered?
App.register('controller:adminMyController', AdminMyController, { singleton: false });
export default AdminMyController;
Previously, because App was a global, I could register this right in the same class.
Am I going to have to move all the register calls to an initializer so I can get access to the app instance?
I belive an initializer would do this for you. You'll need to create an initializers folder in your app directory (same level as controllers, templates, etc). This file should go there.
import Ember from 'ember';
var AdminMyController = Ember.ObjectController.extend({
...
});
export default {
name: 'adminMyController',
initialize: function (container, application) {
container.register('controller:adminMyController', AdminMyController, {singleton: false});
}
};

Categories

Resources