Assertion Failed: The key provided to set must be a string, you passed (generated pokemon.detalhes controller)


#1

I have a {{link-to}} that passes an ID to the detalhes.js route. This route findRecord my model passing the {{link-to}} ID. The payload loads all the data, but when the page finishes loading it comes the error. I didn’t find the “key” and i don’t have a pokemon.detalhes controller. Ember 2.18.1

Error: Assertion Failed: The key provided to set must be a string, you passed (generated pokemon.detalhes controller).

My Code: adapter.js

import DS from 'ember-data';
import { computed } from '@ember/object';

export default DS.RESTAdapter.extend({

    host: 'http://127.0.0.1:8000',
    namespace: 'api/v2',
	headers: computed(function () {
		return {
			'accept': 'application/json'
        };
    }),

    pathForType(type) {
		return type;
	},
/*
    query(store, b, query) {
        store.serializerFor('pokemon').set('pageSize', query.limit);
        const url = `${this.get('host')}/${this.get('namespace')}/pokemon`;
        console.log(url);
        return this.ajax(url, 'GET', {data: query});
    },
*/
    updateRecord(store, type, snapshot) {
		const data = snapshot.record.serialize();
		const headers = Object.assign({}, this.get('headers'), { "pokemon-edit": true });
		const url = this.buildURL(type.modelName, snapshot.id, snapshot, 'updateRecord');
		return this.ajax(url, 'PUT', { headers, data });
	}
});

serializer.js

import DS from 'ember-data';
import _ from 'lodash';

export default DS.RESTSerializer.extend({
  
normalizeResponse(store, primaryModelClass, payload) {
  debugger  
  return  {
        meta: {
          count: payload.count,
          previous: payload.previous,
          next: payload.next 
        },

        data: 
            payload.results && _.map(payload.results, item => {
              return {
                id: (/.+\/([0-9]+)\//.exec(item.url) || [])[1] || 0,
                type: 'pokemon',
                attributes: item
              }
            }) || {
                    type: 'pokemon',
                    id: payload.id,
                    attributes: Object.assign(payload) 
                  }
    };
  },
});

route/index.js

import Route from '@ember/routing/route';

export default Route.extend({
    model(){
        return this.store.query('pokemon', {limit: 2});
    }
});

index.hbs

<table class="table table-striped">
    <thead class="thead-dark">
        <tr>
        <th scope="col">Id</th>
        <th scope="col">Pokemon</th>
        <th scope="col">Ações</th>
        </tr>
    </thead>
    <tbody>
        {{#each model as |poke|}}
            <tr>
                <th scope="row">{{poke.id}}</th>
                <td>{{sentence poke.name}}</td>
                <td>{{#link-to "pokemon.detalhes" poke.id}}<p class="btn btn-success">Detalhes</p>{{/link-to}}</td>
            </tr>
        {{/each}}

    </tbody>
</table>

payload data from index route

{…}
count: 949
next: "http://127.0.0.1:8000/api/v2/pokemon/?limit=2&offset=2"
previous: null
results: […]
0: {…}
  name: "bulbasaur"
  url: "http://127.0.0.1:8000/api/v2/pokemon/1/"
1: {…}
  name: "ivysaur"
  url: "http://127.0.0.1:8000/api/v2/pokemon/2/"
length: 2

route/pokemon/detalhes.js

import Route from '@ember/routing/route';

export default Route.extend({
    model(params) {
		return { params };
	},

	setupController(controller, model) {
		this.store.findRecord('pokemon', model.params.id).then(response => {
			this.set(controller, 'model', response);
			return response;
		})
	}
});

pokemon/detalhes.hbs

<div class="card" style="width: 20rem;">
    <img class="card-img-top" src={{model.image}} alt="Card image cap">
        <div class="card-body">
        <form>
            <div class="form-group">
                <span class="alert-primary">Pokemon:</span>
                <span class="form-control">{{model.name}}</span>
            </div>
            <div class="form-group">
                <span class="alert-primary">XP Base:</span>
                <span class="form-control">{{model.height}}</span>
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
        </form>  
        </div>
</div>

model/pokemon.js

import DS from 'ember-data';
import { computed, get } from '@ember/object';

export default DS.Model.extend({

    name: DS.attr('string'),
    url: DS.attr(),
    height: DS.attr('number'),
    weight: DS.attr('number'),
    base_experience: DS.attr('number'),
    sprites: DS.attr(),

    image: computed('sprites', function(){
        const img = get('sprites');
        return img.get('sprites.front_default');
    })
});

payload data from details route with id=1

{…}
abilities: Array [ {…}, {…} ]
base_experience: 64
forms: Array [ {…} ]
game_indices: Array [ {…}, {…}, {…}, … ]
height: 7
held_items: Array []
id: 1
is_default: true
location_area_encounters: "/api/v2/pokemon/1/encounters"
moves: Array [ {…}, {…}, {…}, … ]
name: "bulbasaur"
order: 1
species: Object { url: "http://127.0.0.1:8000/api/v2/pokemon-species/1/", name: "bulbasaur" }
sprites: Object { back_default: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png", back_shiny: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png", front_default: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png", … }
stats: Array [ {…}, {…}, {…}, … ]
types: Array [ {…}, {…} ]
weight: 69

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('pokemon', function() {
    this.route('edit');
    this.route('edit', { path: 'edit/:id' });
    this.route('detalhes');
    this.route('detalhes', { path: 'detalhes/:id' })
  });
});

export default Router;

#2

The code you posted for your index.hbs has the following in it:

<td>{{#link-to "pokemon.detalhes" poke.id}}<p class="btn btn-success">Detalhes</p>{{/link-to}}</td>

Which I’m guessing is causing the error. What does your router.js file look like?


#3

Oh sorry, my mistake!! I typed wrong my routes. Edited with the corrections (it’s detalhes.js instead detail.js) added router.js and ember version


#4

I found the problem, it’s the setupController.
I rewrote detalhes router and works!!

route/pokemon/detalhes.js

export default Route.extend({
    model(params) {
		return this.store.findRecord('pokemon', params.id)
	},