How to use reopenClass in Ember CLI


#1

Hi guys.

As I’m very new to ember/ember CLI I wanted to learn some basics by following a tutorial. The tutorial is in “plain” Emberjs and there are only the two main files index.html and app.js.

I wanted to “translate” the tutorial to Ember CLI, but I’m stuck at a point where in the tutorial a model is reopened with .reopenClass and I don’t know how to handle it in Ember CLI.

// The RedditLink model
App.RedditLink = Ember.Object.extend({

	thumbnailUrl: function() {
		var thumbnail = this.get('thumbnail');
		return (thumbnail === 'default') ? null : thumbnail;
	}.property('thumbnail')
});

App.RedditLink.reopenClass({

	findAll: function(subreddit) {
		var links = [];
		
		$.getJSON("http://www.reddit.com/r/" + subreddit + "/.json?jsonp=?").then(function(response) {

			response.data.children.forEach(function (child) {

					links.pushObject(App.RedditLink.create(child.
		});
		return links;		
	}
});

In my tranlated EmberCLI project I got the model in my redditlinks.js like so

import DS from 'ember-data';

export default DS.Model.extend({
  thumbnailUrl: function() {
        var thumbnail = this.get('thumbnail');
        return (thumbnail === 'default') ? null : thumbnail;
    }.property('thumbnail')
});

Hope someone could help me :slight_smile: Thanks in advance.

If you need to have a look at the source of the tutorial you can download it here: SOURCE


#2

I don’t think you should need to reopen the class. But if you really want to just do

MyModel = DS.Model.extend({});

MyModel.reopenClass({});
export default MyModel;

#3

Model.findAll is a “class” method, so it requires reopenClass to define such a method.

I wanted to “translate” the tutorial to Ember CLI, but I’m stuck at a point where in the tutorial a model is reopened with .reopenClass and I don’t know how to handle it in Ember CLI.

You would do something like below. Enjoy & good luck with Ember!

import Ember from 'ember';

var Model = Ember.Object.extend({
	thumbnailUrl: function() {
		var thumbnail = this.get('thumbnail');
		return (thumbnail === 'default') ? null : thumbnail;
	}.property('thumbnail')
});

Model.reopenClass({
	findAll: function(subreddit) {
		return new Ember.RSVP.Promise(function(resolve) {
			// todo: handle the error case and replace with ic-ajax:
                        // https://github.com/instructure/ic-ajax
			Ember.$.getJSON('http://www.reddit.com/r/' + subreddit + '/.json?jsonp=?').then(function(result) {
				resolve(result.data.children.map(function (child) {
					return Model.create(child);
				}));
			});
		});
	}
});

export default Model;

#4

Thank you very much @jasonmit that helps a lot. I have now read a little about Ember.RSVP and it seems easy to use, but I’m not quite getting the point on how I can access the .findAll -method in my controller.

At the moment I got something like this for my controller:

    import Ember from 'ember';
    import RedditLinks from "../models/redditlinks.js";
    
    export default Ember.Controller.extend({
      subredditHeader: "aww",
      actions: {
        loadList: function() {
          // Grab the value from the input field
          var value = this.get('subreddit');
          console.log("loadList is working");
    
          if (value) {
    
            this.set('subredditHeader', value);
            this.set('model', RedditLinks.findAll(value));
    
            // Clear out the input field
            this.set('subreddit', '');
    
          }
        }
      }
    });

This end up in an quite obvious console error:

Error while processing route: redditlinks Could not find module `series-control-api/models/redditlinks.js` imported from `series-control-api/controllers/redditlinks` Error: Could not find module `series-control-api/models/redditlinks.js` imported from `series-control-api/controllers/redditlinks`

How do i properly access the .findAll method?

I kind of feel stupid to ask that but it’s not that easy for me to get into embercli, as I wish it would be. Once a gain thank you very much in advance. :slight_smile:


#5

I think you need to drop the .js from your import statement

import RedditLinks from "../models/redditlinks";