Ember, JSONAPIAdapter, JSONAPISerializer, findAll not available - javascript

Im building an Ember app "ember-cli": "2.4.3", sitting on Laravel/Lumen and cant seem to get the wires hooked up correctly. Im trying to also an API server JSON-API compliant, so I have access to alter the syntax if thats a problem.
If I remove the export default DS.JSONAPISERIALIZER, I get ember.debug.js:32116 TypeError: typeClass.eachTransformedAttribute is not a function
With it, I typically get Assertion Failed: You tried to load all records but your adapter does not implement findAll
If I call getJSON(...) from within the route, instead to calling the store for the data, it works perfectly, and displays to the view as expected.
I have tried other adapters but I think that being JSON-API compliant I need to use the JSONAPIADAPTER. Any help would be awesome.
application.js
import DS from "ember-data";
export default DS.JSONAPIAdapter.extend({
namespace: 'v1',
host: 'http://edu-api.app:8000',
});
export default DS.JSONAPISerializer.extend({
//in preparation of underscores in returned data
// keyForAttribute: function(attr) {
// return Ember.String.underscore(attr);
// },
// keyForRelationship: function(attr) {
// return Ember.String.underscore(attr);
// }
});
skill.js
import DS from 'ember-data';
var App = window.App = Ember.Application.extend();
var attr = DS.attr;
App.Skill = DS.Model.extend({
name: attr("string"),
desc: attr("string")
});
index.js
export default Ember.Route.extend({
model() {
//return this.store.findAll('skill'); //<- Assertion Failed: You tried to load all records but your adapter does not implement `findAll`
this.get('store').findAll('skill'); //<- Assertion Failed: You tried to load all records but your adapter does not implement `findAll`
//return Ember.$.getJSON('http://edu-api.app:8000/v1/skills'); //<- works, and properly displays data to view
}
});

I think you primary have problems understanding ember-cli.
First you don't put your adapter and serializer in the same file. Maybe use the generators to get a default file like ember generate serializer application.
Your application serializer goes to app/serializers/application.js, your adapter to app/adapters/application.js.
Next this line looks really really wrong:
var App = window.App = Ember.Application.extend();
This creates a new app, but you should do this only once in your app/app.js. Next you use a global export, what you should never do in an ember-cli app.
To specify your model you need to locate your file under models/skill.js. There you don't attach your new Model to a global exported App like App.Skill = DS.Model.extend({, but you export it as default export like export default DS.Model.extend({.
Your index.js looks right if its located under routes/.
I strongly recommend you to read more about the ember resolver, and the ember dependency injection framework which do all this magic for you. Also use the generators to get your files, it can help you to place your files right.

Related

Nuxtjs custom module

I'm quite new to Nuxtjs so I made a test project which purpose is merely the (of course) testing of Nuxtjs functionalities.
Currently I'm trying to create a simple custom module: afaik a module is basically a wrapper around a vou/js library/plugin, something like a high-level integration used to expose configurations on how the underlying library/plugin is imported and used in the Nuxt application.
So I'm trying with a simple module that declare some plain js classes that I'll use in my application, e.g. Order and Product, and that's what I came out with:
Directory structure
pages
the-page.vue
modules
classes
index.js
order.js
/modules/classes/index.js
const path = require('path')
export default function (moduleOptions) {
const { nuxt } = this
// add the debug plugin
this.addPlugin({
src: path.resolve(__dirname, 'order.js'),
})
}
/modules/classes/order.js
class Order {
constructor(id) {
this.id = id;
console.log('created order #' + this.id);
}
}
export {Order};
/nuxt.config.js
export default {
// ...
buildModules: [
// ...
'~/modules/classes'
],
// ...
}
/pages/the-page.vue
<script>
export default {
name: 'ThePage',
data () {
return {
}
},
methods: {
createOrder () {
const order = new Order(123)
}
}
}
</script>
The error
My defined class are still not imported in my pages:
/app/pages/the-page.vue
18:13 error 'order' is assigned a value but never used no-unused-vars
18:25 error 'Order' is not defined no-undef
Considerations
Probably I'm missing something about modules usage and/or implementation, but every tutorial I found starts with too complex scenarios, and since I'm at the beginning with Nuxtjs I need something easier to implement.
Ok, I found out that I was mistaken how NuxtJs modules are intended to work and was traying to do somenthing they are not intended for.
Nuxt modules cannot import js classes in every component of the application as I wanted to do, they just "add a property" to the main application instance that is made accessible through this.$<something>, like e.g. you can already do in simple Vue with the Vue Router or the Vuex store plugins that give access to the this.$router and this.$store properties.
NuxtJs modules just wrap simple plugins and expose configuration options to made.

How to structure Meteor app and load into Meteor shell

I'm having a number of issues putting together a very simple piece of code as I learn Meteor. See the comments, which are questions.
server/main.js
import { Meteor } from 'meteor/meteor';
import { Post } from './schema'
// Why is this required to make Post available in Meteor.startup?
// Isn't there auto-loading?
Meteor.startup(() => {
console.log(Post)
// This works, but why isn't Post available to meteor shell?
});
server/schema.js
import { Post } from './models/post'
export { Post }
server/models/post.js
import { Class } from 'meteor/jagi:astronomy';
// Why can't this be imported elsewhere, like main.js?
const Posts = new Mongo.Collection('posts');
const Post = Class.create({
name: 'Post',
collection: Posts,
fields: {
title: { type: String },
userId: String,
publishedAt: Date
},
});
export { Post }
In addition to these questions, how can I load my app into meteor shell? Post is undefined there, even though it's defined in Meteor.startup. I tried using .load with an absolute path, but this breaks my app's imports, which use relative paths.
As for which errors I'm confused about:
When I try and use import inside Meteor.startup(), I get an error that the keyword import is undefined. I'm using the ecmascript package.
When I don't import { Class } in the same file where I use Class, I get an unknown keyword error.
If I don't import { Post } in main.js, then Post is undefined.
Not able to load app into Meteor shell.
To access exported objects in Meteor shell, use require:
> require('server/schema.js').Posts.findOne();
To access objects exported by packages, use the package name:
> require('react').PropTypes;
The reason you can't access an object that's imported by another js file is that each file has its own scope here. When Meteor builds your app, it doesn't just concatenate js files like many other build systems do, and that's really a good thing.
Basically a Javascript object gets created for every js file you write. Anything you export in a js file becomes a field in this object which you can access by using require. And import is just a nicer version of the same thing.

Using JSON Api URL EmberJS

I normally get data from a service I created, a hard-coded JSON. But I need to take the JSON from an URL.
This is my twiddle :
https://ember-twiddle.com/b9cd8b1b3418d876f88235c4aa99e268?openFiles=templates.pic.hbs%2Ctemplates.components.image-list.hbs14
How can I add a URL as a source instead of calling it from the service 'pics'? I tried something but got errors and couldn't do anything. I'm very new at this.
I tried
model() {
return $.getJSON('/my-url');
}
But I get this error :
Mirage: Your Ember app tried to GET 'my URL', but there was no route defined to handle this request. Define a route that matches this path in your mirage/config.js file. Did you forget to add your namespace?
I totally had no idea about the error because I don't use mirage, I created it yeah but didn't use in any part of the project.
Then I tried :
import Ember from 'ember';
export default Ember.Route.extend({
model() {
this.get('my Json url', () => {
return [];
});
}
});
Now chrome's devTool doesn't give any error but all I see is a blank-page. Is this all wrong or is it something about the .hbs files?
Any ideas?Thanks!
Uninstall ember-cli-mirage and go back to:
model() {
return $.getJSON('/my-url');
}
I figured what the problem was with some help :
Solution:
In my index.js, I should have used
{{image-list model=model.Data currentPos=currentPos }}
instead of
{{image-list model=model currentPos=currentPos }}
Also, I don't need any model/*.js because I get the model() from IndexRoute so I deleted those files. Thanks

Emberjs loadInitializer error

Not sure how to correct this error. I'm following along with this screencast https://www.youtube.com/watch?v=vLXGKNA4P_g and it appears that the update to Ember breaks functionality.
DEPRECATION: `lookup` was called on a Registry. The `initializer` API
no longer receives a container, and you should use an `instanceInitializer` to look up objects from the container.
See http://emberjs.com/guides/deprecations#toc_deprecate-access-to-
instances-in-initializers for more details.
I'm new to Ember and have found the https://github.com/emberjs/data/issues/3051 thread on github but I'm not quite sure how to fix this. This is my app.js file
import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';
import config from './config/environment';
var App;
Ember.MODEL_FACTORY_INJECTIONS = true;
App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver: Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;
Can someone explain how to make this compliant with the error? The documentation suggests this:
http://emberjs.com/deprecations/v1.x/#toc_deprecate-access-to-instances-in-initializers
But being new to Ember, I'm not sure what this means or how to implement it.

How do I access the Ember global 'App' variable in an Ember CLI application?

I am creating an Ember application using the Ember CLI. I have a view which invokes a component that I created. I am trying to access the global App variable to create my component and insert it into my layout.
The error: Uncaught ReferenceError: App is not defined
How do I fix this?
app.js
import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';
Ember.MODEL_FACTORY_INJECTIONS = true;
var App = Ember.Application.extend({
modulePrefix: 'client-web', // TODO: loaded via config
Resolver: Resolver
});
loadInitializers(App, 'client-web');
export default App;
item-table.js (This is a view)
import Ember from 'ember';
export default Ember.View.extend({
templateName: 'item-table',
didInsertElement: function() {
// All my other code here
App.FreestyleChartComponent.create().appendTo($('#wp-chart td')); // This throws an error.
}
});
app/components/freestyle-chart.js
import Ember from 'ember';
export default Ember.Component.extend({
templateName: 'components/freestyle-chart',
didInsertElement: function() {
console.log('Inserted the component.');
}
});
I can think of two ways. The first is to put the App in the global scope manually.
var App = window.App = Ember.Application.extend();
The second is to import the App into your view:
import App from './path/to/app/file';
The latter is only possible if Ember CLI supports circular references. The official ES6 spec supports them but many transpilers don't (mine doesn't).
However, I don't think this is your root concern. For the most part, you shouldn't be accessing global variables in Ember CLI. Instead of placing the FreestyleChartComponent in the App namespace, why not just put it in a module and import it like any other module? Global variables are unavoidable (I experienced that today), but you should try to minimize them.
I do agree that you should not be accessing your app via the global namespace, however ember-cli actually does actually make you app a global with the name of your app being the name of the variable.
If you open /app/index.html in your ember-cli project you should see a script tag towards the bottom that looks like...
<script>
window.YourAppName = require('your-app-name/app')['default'].create(YourAppNameENV.APP);
</script>
in the above example YourAppName would be your app available as a global
Import the component that you want:
import FreestyleChartComponent from 'app_name/app/components/freestyle-chart';
There is no straight forward way to do this since Ember CLI wants you to use the public API and its given components rather than accessing the App instance directly.
Most solutions consist of making the App instance global, whereby this one does not. I did not test this, but I think this should work:
appname/utils/application.js
export default {
instance: null
};
appname/instance-initializers/application.js
import application from 'appname/utils/application';
export default {
name: 'app-initializer',
initialize: function (application) {
application.instance = application;
}
};
Now
import application from 'appname/utils/application';
and use application.instance in any file where you need the application instance.
Justed tested with Ember 3.7.
import App from 'app-name/app';
app-name has to be replace with the name of your app (I guess the one in package.json).

Categories