Ember: Error while processing route. Can't hit API - ember.js

This code works (hardcoded):
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
let stars = [
{
key: "johnlennon",
logoUrl: "https://www.images.com/johnl.png",
name: "John Lennon",
alive: false
}
}
}
});
When I do this, it doesn't (from API):
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import config from '../../../../../config/environment';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
const token = this.get('session.data.authenticated.token');
return Ember.RSVP.hash({
stars: Ember.$.getJSON(Ember.$.getJSON(`${config.APP.starsAPI}/api/stars?authorizationToken=${token}`))
});
}
});
The error I receive:
jquery.js:9175 GET
http://localhost:4242/stars/948/connect/[object%20Object] 404 (Not
Found)
ember.debug.js:30291 Error while processing route:
stars.show.connect.stars.index
As you may have guessed, I need it to work from API. Why is that giving me the error?

It worked after this change:
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import config from '../../../../../config/environment';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
const token = this.get('session.data.authenticated.token');
return Ember.$.getJSON(`${config.APP.starsApi}/api/stars?authorizationToken=${token}`).then(function(retVal){
return retVal;
});
}
});

Looks like you had chained `Ember.$.getJSON() methods.
return Ember.$.getJSON(`${config.APP.starsApi}/api/stars?authorizationToken=${token}`).then(function(retVal){
return retVal;
});
This should work fine

Related

How to pass Error Message to Route from a different Controller in Ember js

Let, I have two routes and two controllers namely login and signup
If I signup successfully then I want to perform transition to the route login with a success message as parameter,
/app/signup/controller.js
import Controller from '#ember/controller';
export default Controller.extend({
actions: {
signup: function(){
let _this = this;
let successMessage = 'successfully registered';
var credentials = this.getProperties('name','identification','password');
let list = this.store.createRecord('user', {
name: credentials.name,
email: credentials.identification,
password: credentials.password
});
list.save().then(function(){
_this.transitionToRoute('login','successMessage');
});
}
}
});
app/login/template.hbs
<body>
{{successMessage}}
</body>
/app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('login');
this.route('signup');
});
export default Router;
I think you sort of have 3 options:
Use a route param (query param or positional)
Use a service to manage login stuff, and read some computed property from the service representing your state / message from your login controller
Use a flash/toast style UI where the message lives outside of the app view/component hierarchy
Personally, for where you want to display your message, I'd go for #2, which would look like this:
// app/services/user-session.js
import Service from '#ember/service';
export default class extends Service {
successMessage = null;
signup(name, id, password) {
// logic
this.set('successMessage', 'yay');
}
}
// app/controllers/signup.js
import Controller from '#ember/controller';
import { service } from '#ember-decorators/service';
import { action } from '#ember-decorators/object';
export default class extends Controller {
#service userSession;
#action
signup() {
this.userSession.signup(...);
this.transition...
}
}
// app/controllers/login.js
import Controller from '#ember/controller';
import { service } from '#ember-decorators/service';
import { readOnly } from '#ember-decorators/object/computed';
export default class extends Controller {
#service userSession;
#readOnly('userSession.successMessage') successMessage;
}
Or, in the old syntax:
// app/services/user-session.js
import Service from '#ember/service';
export default Service.extend({
successMessage: null,
signup(name, id, password) {
// logic
this.set('successMessage', 'yay');
}
});
// app/controllers/signup.js
import Controller from '#ember/controller';
import { inject as service } from '#ember/service';
export default Controller.extend({
userSession: service(),
actions: {
signup() {
this.userSession.signup(...);
this.transition...
}
}
});
// app/controllers/login.js
import Controller from '#ember/controller';
import { inject as service } from '#ember/service';
import { readOnly } from '#ember/object/computed';
export default Controller.extend({
userSession: service(),
successMessage: readOnly('userSession.successMessage')
});
hope this helps

Using and binding JSONAPI attributes data in ember js

I have an ember.js toy application that I want to hook into a JSONAPI REST service for obtaining and displaying data. I can trace in my browser's developer console, that indeed, ember-data initiates the appropriate GET requests and receives proper, valid JSONAPI response bodies.
// ./app/models/person.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
birthdate: DS.attr('string')
});
// ./app/adapters/person.js
import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({
pathForType() {
return "persons";
}
});
// ./app/adapters/application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'http://localhost:5000'
});
// ./app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function () {
this.route('persons', function() {
this.route('show', { path: '/:person_id' });
});
});
export default Router;
// ./app/routes/persons/show.js
import Route from '#ember/routing/route';
export default Route.extend({
model(params) {
return this.get('store').findRecord('person', params.person_id);
}
});
// ./app/routes/persons/index.js
import Route from '#ember/routing/route';
export default Route.extend({
model() {
return this.get('store').findAll("person");
}
});
// ./app/routes/application.js
import Route from '#ember/routing/route';
export default Route.extend({
});
// ./app/app.js
import Application from '#ember/application';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
const App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;
// ./app/resolver.js
import Resolver from 'ember-resolver';
export default Resolver;
Unfortunately, when I want to use the model in my template, I can only access the element ids, and not the data attributes like name (Remains empty when rendered).
<!-- ./app/templates/persons/index.hbs -->
{{#each model as |person index|}}
<li>
Person {{person.id}} {{index}}
{{person.name}}
{{#link-to 'persons.show' person }}
Link {{index}}
{{/link-to}}
</li>
{{/each}}
I am a bit at loss for why this happens. Am I doing something wrong?
The posted code is fine, the attributes I was missing in the templates was actually missing from the HTTP responses.

The same model but not the same query params could not set in one route by ember

My ember version:
---------------------------
Ember : 2.10.2
Ember Data : 2.10.0
jQuery : 2.2.4
Ember Simple Auth : 1.1.0
Model Fragments : 2.3.2
---------------------------
My route code like:
import Ember from 'ember';
import RSVP from 'rsvp';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
return RSVP.hash({
orderTransactionTypes: this.store.query('transactionType', {
filter: {
category: 'order_category'
}
}),
otherTransactionTypes: this.store.query('transactionType', {
filter: {
category: 'transaction_category'
}
})
});
},
setupController(controller, model) {
controller.set('model', model);
}
})
In RSVP.hash all data come from transactionType, but they have not same query params. I use this way set model will have a problem is model. orderTransactionTypes and model.otherTransactionTypes become same data.
Whey this problem is happened? And how can I fix this problem? Thanks.

How do I get cookies to to be sent with my requests to the backend in ember app?

Is there a way in Ember to send cookies with the requests to the backend?
For example: if my client URL is protocol://example.com. The cookies that belong to the same domain will be in the request header when I navigate to protocol://example.com/profile. However, they do not persist in the subsequent request/s the profile route model method makes -> example to protocol://example-host/posts. How do I make those cookies persist?
/app/routes/profile.js:
import Ember from "ember";
import AuthenticatedRouteMixin from "simple-auth/mixins/authenticated-route-mixin";
export default Ember.Route.extend({
model() {
return this.store.findAll("post");
},
renderTemplate() {
this.render("header", {
outlet: "header"
});
this.render("profile");
}
});
/app/adapters/application:
import Ember from "ember";
import DS from "ember-data";
export default DS.RESTAdapter.extend({
host: 'http://example-host.com',
corsWithCredentials: true,
crossDomain: true,
xhrFields: { withCredentials: true }
});
This works in my production app. Code in app/adapters/application.js:
import Ember from 'ember';
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
export default DS.RESTAdapter.extend({
ajax(url, method, hash) {
hash = hash || {};
hash.crossDomain = true;
hash.xhrFields = {
withCredentials: true
};
return this._super(url, method, hash);
}
})
You can also set individual header values to be sent with each ember-data request. Useful if you need to pass an API key with all your requests.
In your adapter (app/adapters/application.js):
import DS from 'ember-data';
import { get } from '#ember/object';
import { computed } from '#ember/object';
export default DS.RESTAdapter.extend({
headers: computed(function() {
return {
'API_KEY': get(document.cookie.match(/apiKey\=([^;]*)/), '1'),
'ANOTHER_HEADER': 'Some header value'
};
}).volatile()
});

ember.js: Make AdminRouteMixin from AuthenticatedRouteMixin?

Is there a more elegant way to prevent unauthorized access to an admin-only route than writing this in all of my admin routes?
export default Ember.Route.extend(AuthenticatedRouteMixin, {
beforeModel: function(){
if(!this.get('session.secure.admin')) this.transitionTo("dashboard");
}
});
Perhaps it's possible to extend AuthenticatedRouteMixin itself to make this kind of check?
Thanks!
Why not just make the mixin?
import Ember from 'ember';
import AuthenticatedRouteMixin from 'wherever/it/is'.
const { Mixin } = Ember;
export default Mixin.create(AuthenticatedRouteMixin, {
beforeModel(){
if(!this.get('session.secure.admin')) {
this.transitionTo("dashboard");
}
}
})
And then import it in your routes:
import Ember from 'ember';
import AdminCheckMixin from 'yourApp/mixins/routes/admin-check';
const { Route } = Ember;
export default Route.extend(AdminCheckMixin);