I'm trying define a Person class within an Ember-cli project which I can then call from within a service. I've got a basic service working that updates when various inputs are changed but I can't reference the Person class at all. This is what I currently have:
# app/models/person.js
import Ember from "ember";
var Person = Ember.Object.extend({
helloWorld: function() {
alert("Hi, my name is " + this.get('name'));
}
});
export default Person;
and in the router I've got:
# app/router.js
import Ember from 'ember';
import config from './config/environment';
import Person from './models/person';
var Router = Ember.Router.extend({
location: config.locationType,
model: function() {
return Person.create({
name: "Tom Dale"
});
}
});
I'm pretty sure it's referenced the "import Person" correctly because if it's wrong I see an error about the file not being found.
then in the service I've got:
# /app/services/calculator.js
import Ember from 'ember';
export default Ember.Service.extend({
init: function () {
// this gives "Person is not defined"
const person = new Person();
// this gives "Person is not defined"
const person = Person.create({ name: "Tom Jones" });
// this gives "store not defined"
const person = this.store.createRecord('person', { name: "Tom Jones" });
},
});
Any pointers on how I can access the Person class from the service would be greatly appreciated. Thanks!
I'll try to address what I think are some misunderstandings.
First off, you have a Person class but it isn't a DS.Model so you won't be able to use it through Ember Data (this.store).
Your router.js file is where you define your routes, as shown in the guides. You seem to be confusing it with how to specify a route's model? Pay close attention to the file paths in the code samples.
As for the service, Person is not defined because unlike your router.js code, you are not importing Person into the module. Imports are per-module, so you also need import Person from './models/person'; in your service. Check jsmodules.io for more information.
Ember Data's store is injected into Routes and Controllers only, that's why this.store is undefined in the Service. If you want to access the store, do the following:
export default Ember.Service.extend({
store: Ember.inject.service(),
init() {
const person = this.get('store').createRecord('person', { name: "Tom Jones" });
}
});
Mind you, the above should not work with the code you posted as Person isn't a DS.Model
You need to import Person in every file that references it.
Add import Person from './models/person'; to your service class.
Related
I need to check if there are any variables in App.js and then check their type. I checked all the docs for jest, enzyme and react testing library but found nothing useful.
If anyone can give me a hand it'll be very much appreaciated. Sharing my code below.
App.js:
const names = ["George", "Lewis", "Max", "Charles", "Fernando"];
const surnames = ["Pedrosa", "Rossi", "Crivillé", "Márquez", "Lorenzo"];
return <div className="App"></div>;
}
export default App;
Test:
import Adapter from "enzyme-adapter-react-16";
import "#testing-library/jest-dom";
import Test from "../../block02/ex02/src/App.js";
import { screen, render } from "#testing-library/react";
configure({ adapter: new Adapter() });
describe("b2ex02: Display name and surname side by side", () => {
it("Declare two arrays", () => {
// here I need to select the "names" and "surnames" variables and check that they are typeof array
});
});
If I can provide any other useful piece of information I will be happy to. Thanks!
Edit
I fully recommend testing variable existence through some kind of using them. Otherwise this has proven imposible to achieve.
I am trying to grasp the underlying system of Ember.JS. Whereto are those Ember-Objects exported and how are they used?
components:
export default Ember.Component.extend({ ... });
controllers:
export default Ember.Controller.extend({ ... });
models:
export default DS.Model.extend({ ... });
routes:
export default Ember.Route.extend({ ... });
... they all follow the same structure: they extend some object and export something.
Somebody knows more? Thanks!
I think you are interpreting the export keyword wrong here.
It doesn't mean files are written somewhere else in a different format, but:
if a module (= file) is imported, then things in that file that are exported are available to the importer.
Think of it as making some parts available to other modules, a public API in shorter terms.
Ember files usually only export one thing as there is a strong naming convention making the Ember engine work that way.
This is why if you declare a /user route, it will try to use your routes/user.js, controllers/user.js, and templates/user.hbs files if they exist, without you having to specify anything.
In a similar way, this is what makes a component usable inside a template.
Hence the one-liner export default Ember.Something.extend({ ... }); you find in these files.
However, you can have modules (= files) with multiple export statements in a single file, this is perfectly valid.
// Example from babel website
// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
return Math.exp(x);
}
// app.js
import exp, {pi, e} from "lib/mathplusplus";
console.log("e^π = " + exp(pi));
The Learn ES2015 from Babel website has a few examples, and you can read more about the export statement on MDN.
In Ember applications, you will - from my experience - find files with multiple exports mostly in some directories meant to be used by more than one module in the application, or not bound to the Ember engine auto-import, like some utils.
The following example shows an Ember.Controller importing a variable exported from another module:
// utils/messages.js
export var hello = 'Hello!';
export var bye = 'Good Bye!'
// controllers/hello.js
import { hello } from "utils/messages";
export default Ember.Controller.extend({
firstName: 'David',
helloString: Ember.computed('firstName', function(){
return `${hello} ${this.get('firstName')}`;
})
});
I'm working on migrating an App from JavaScript\Ionic\Angular1 to Typescript\Ionic2\Angular2 one file at a time. I've poured over dozens of how-to's and such about migrating from one to the other, done the Angular 2 quick start and tutorial, and seen how to go from .js to .ts as well as installed all of the npm packages I need. Assuming I have everything I need to start the migration process, I really need help actually starting. I have dozens of files to convert, and it would help me greatly to just get one file converted correctly with the old code commented out to use as a reference to convert the others.
Here is a sample file. If you could convert this for me, or walk me through converting it, I would be very appreciative.
angular.module('myApp.app', ['ionic'])
.controller('myApp.app', function($rootScope, $scope, AService, BService, CService){
$scope.setUserName = function (user){
$scope.user = user;
};
document.addEventListener('deviceready', function() {
$rootScope.$on('$cordovaNetwork:online', function (e, nState) {
BService.setOnline(true);
})
})
})
Thank you.
The code below is not complete, but gives you an idea of the direction you should be heading. It is a modified version of the boilerplate code that is created for you whenever you use the ionic-cli to generate a new app.
You would define your services each in a separate file in a subfolder of your app/ folder called services. For example, your AService would be defined in app/services/a-service.ts. You import app level services at the top of your app.ts file and then include them in an array as the second component to the ionicBootstrap() function at the very bottom of the file. You also have to inject them as private variables in the constructor() of your MyApp component.
There is no longer anything like a $scope or $rootScope where you can store app-wide variables. Instead, you would create a provider (e.g. UserData) that you would use to store data that needs to be persisted across pages or sessions.
I recommend reading through the Ionic 2 Conference Application, which has been developed as a sample app using the Ionic 2 framework by its developers. It shows you how to handle things like user login, and persisting data across the app.
import { Component } from "#angular/core";
import { ionicBootstrap, Platform, Nav } from "ionic-angular";
import { AService } from "./services/a-service";
import { BService } from "./services/b-service";
import { CService } from "./services/c-service";
import { UserData } from "./providers/user-data";
import { HomePage } from "./pages/home/home";
#Component({
templateUrl: "build/app.html"
})
export class MyApp {
// the root nav is a child of the root app component
// #ViewChild(Nav) gets a reference to the app's root nav
#ViewChild(Nav) nav: Nav;
rootPage: any = HomePage;
pages: Array<{ title: string, component: any }>;
constructor(
private platform: Platform,
private aSvc: AService,
private bSvc: BService,
private cSvc: CService,
private userData: UserData
) {
this.initializeApp();
// array of pages in your navigation
this.pages = [
{ title: "Home Page", component: HomePage }
];
}
initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
bSvc.setOnline(true);
});
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
}
// Pass the main app component as the first argument
// Pass any providers for your app in the second argument
// Set any config for your app as the third argument:
// http://ionicframework.com/docs/v2/api/config/Config/
ionicBootstrap(MyApp, [AService, BService, CService, UserData]);
I try to use the Restadapter from emberjs to call my api under 'http://local.ember.api' but I can't get any data. After some respearch I didn't get it working. Here is my code:
I created a file under app/application with the name adapter.js with this code:
import DS from 'ember-data';
import $ from 'jquery';
import config from '../config/environment';
var ApplicationAdapter;
ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://local.ember.api',
namespace: 'api/v1'
});
var ApplicationSerializer;
ApplicationSerializer = DS.RESTSerializer.extend({});
export default ApplicationAdapter;
export default ApplicationSerializer;
and under app/models I have a user.js with this code:
import Ember from 'ember';
import DS from 'ember-data';
var User = DS.Model.extend({});
export default User;
my app/router.js looks like this:
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('users');
this.route('user', {path: '/user/:user_id'});
});
export default Router;
and my app/routes/user.js:
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.find('user', params.user_id);
}
});
with this setup I get this error:
Error: Assertion Failed: You tried to find a record but your adapter (for test-app#model:user:) does not implement 'findRecord'
when I create a file under app/services with the name store.js and this code:
import Ember from 'ember';
import DS from 'ember-data';
var Store;
Store = DS.Store.extend({});
export default Store;
I get this error:
Error: Assertion Failed: You tried to find a record but your adapter (for test-app#model:user:) does not implement 'findRecord'
when I create a function with the name 'findRecord' in the store.js-File:
Store = DS.Store.extend({
findRecord: function() {}
});
I get no result. Where is the mistake?
I think the problem is that you are calling find on the Store, but the according to the documentation you should be calling findRecord as there is no find. Hence, the error message.
When you create the findRecord method, it's probably being called but since you don't return anything... well you don't get any data back. If you console.log there, it's probably being called.
Edit:
I found the line where that error happens in ember-data's source code (although it's from master). But looking at the source code form 1.13.15 it should have the find method and it should give you a warning.
Can you setup an EmberTwiddle that reproduces the issue?
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});
}
};