2
votes

I'm new to Ember.js and I'm trying to create an application that mimics Youtube by using their API. Currently I have a route that is responsible for grabbing the initial information from the Youtube Api to populate the page on load. I have a search bar component that is used to gather the input from the user and repopulate the list with results based on the string. The problem is that while I am getting the input from the user my Route model is not refreshing to grab the update data from the api. Below is my code.

Template for my video route video.hbs:

// app/templates/video.hbs
<div class="row">
  {{search-bar}}
<div class="row">
  <div class="col-md-12">
    <hr>
    <br>
  </div>
</div>
<div class="row">
  <div class="col-md-8">
    <div class="row">
      {{video-list model=model}}
        <div class="col-md-4 pull-right video-container">
          {{#if  videoId}}
            <iframe id="video-player" src="https://www.youtube.com/embed/{{videoId}}"></iframe>
          {{else}}
            <iframe id="video-player" src="https://www.youtube.com/embed/kEpOF7vUymc"></iframe>
          {{/if}}
        </div>
      </div>
    </div>
  </div>
</div>

Template for my search bar

// app/templates/components/search-bar.hbs
<div class="col-md-12 col-md-offset-4">
    <form class="form-inline">
      <div class="form-group" onsubmit="return false">
        {{input type="text" class="form-control" value=search id="search" placeholder="Search Videos..."}}
      </div>
      <button type="submit" {{action "updateSearch"}}class="btn btn-success">Search</button>
    </form>
</div>

Component for my search bar

// app/components/search-bar.js
import Ember from 'ember';

export default Ember.Component.extend({
  userSearch: "",
  actions: {
    updateSearch: function() {
      this.set("userSearch", this.get("search"));
      this.modelFor("videos").reload();
    }
  }
});

Video Route

// app/routes/video.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    var userSearch = this.get("search") === undefined ? "Code" : this.get("search");
    this.set("search", userSearch);
    var url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q="+ userSearch +"&maxResults=50&key="api key goes here";
    return Ember.$.getJSON(url).then(function(data) {
      return data.items.filter(function(vid) {
        if(vid.id.videoId) {
          return vid;
        }
      });
    });
  }
});
1

1 Answers

0
votes

reload - will not call model hook method, in this case, you can send action to video route and try refresh from there.

EDIT:

Adjusting your code for your use case, Let me know if it's not working or anything wrong in this approach.

app/routes/video.js
Here we are using RSVP.hash function for returning multiple model. I am including userSearch too. Its better to implement query parameters for this use case, but I implemented it without using it.

import Ember from 'ember';

export default Ember.Route.extend({
    userSearch: '',
    model: function() {
        var userSearch = this.get("userSearch") === undefined ? "Code" : this.get("userSearch");
        var url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=" + userSearch + "&maxResults=50&key=apikey";
        return Ember.RSVP.hash({
            videosList: Ember.$.getJSON(url).then(function(data) {
                return data.items.filter(function(vid) {
                    if (vid.id.videoId) {
                        return vid;
                    }
                });
            }),
            userSearch: userSearch
        });
    },
    actions: {
        refreshRoute(userSearch) {
            this.set('userSearch',userSearch);
            this.refresh();
        },
    }
});

app/controllers/viedo.js
It contains refreshRoute function and this will call refreshRoute function available in video route file.

import Ember from 'ember';
export default Ember.Controller.extend({
  actions:{
      refreshRoute(userSearch){
          this.sendAction('refreshRoute',userSearch);
      }
  }
});

app/templates/video.hbs
1. I am passing userSearch property and refreshRoute action name to search-bar component
2. Accessing videosList using model.videosList

<div class="row">
  {{search-bar userSearch=model.userSearch refreshRoute="refreshRoute"}}
<div class="row">
  <div class="col-md-12">
    <hr>
    <br>
  </div>
</div>
<div class="row">
  <div class="col-md-8">
    <div class="row">
      {{video-list model=model.videosList}}
        <div class="col-md-4 pull-right video-container">
          {{#if  videoId}}
            <iframe id="video-player" src="https://www.youtube.com/embed/{{videoId}}"></iframe>
          {{else}}
            <iframe id="video-player" src="https://www.youtube.com/embed/kEpOF7vUymc"></iframe>
          {{/if}}
        </div>
      </div>
    </div>
  </div>
</div>

app/components/search-bar.js
Here you will get userSearch property as external attributes ie. it will be passed as an argument on including the component.

import Ember from 'ember';
export default Ember.Component.extend({
    userSearch:'',//external attributes
    actions: {
        updateSearch() {
            var userSearch = this.get('userSearch');
            this.sendAction('refreshRoute',userSearch); //this will call corresponding controller refreshRoute method
        }
    }
});

app/templates/components/search-bar.hbs

<div class="col-md-12 col-md-offset-4">
    <form class="form-inline">
      <div class="form-group" onsubmit="return false">
        {{input type="text" class="form-control" value=userSearch id="search" placeholder="Search Videos..."}}
      </div>
      <button type="submit" {{action "updateSearch"}}class="btn btn-success">Search</button>
    </form>
</div>