Skip to content

Instantly share code, notes, and snippets.

@poteto
Last active March 26, 2020 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save poteto/c0f98a5b62287d4a88fa80be65d3ba0d to your computer and use it in GitHub Desktop.
Save poteto/c0f98a5b62287d4a88fa80be65d3ba0d to your computer and use it in GitHub Desktop.
data loader components
import Ember from 'ember';
import { task, timeout } from 'ember-concurrency';
import GiphyClient from '../lib/giphy-client';
const { Component, computed, get, set, isBlank } = Ember;
const GIPHY_DEBOUNCE = 1000;
export default Component.extend({
init() {
this._super(...arguments);
this.results = [];
},
didReceiveAttrs() {
let query = get(this, 'query');
get(this, 'fetchData').perform(query);
},
giphyClient: computed(function() {
return new GiphyClient('DivqY65FrecXGjVGPHwsVmdBMPOsNsv8');
}),
fetchData: task(function*(query) {
if (isBlank(query)) {
return;
}
yield timeout(GIPHY_DEBOUNCE);
let giphyClient = get(this, 'giphyClient');
let { data } = yield giphyClient.query(query);
return set(this, 'results', data);
}).restartable()
});
import Ember from 'ember';
import QueryParams from 'ember-parachute';
export const AppQueryParams = new QueryParams({
query: {
as: 'q',
defaultValue: 'puppy',
refresh: true
}
});
const { Controller, computed: { or } } = Ember;
export default Controller.extend(AppQueryParams.Mixin, {
queryParamsChanged: or('queryParamsState.{query}.changed')
});
import Ember from 'ember';
import request from 'ember-ajax/request';
const { assert, isPresent } = Ember;
export default class GiphyClient {
constructor(apiKey) {
assert('You must pass an API key to the Giphy Client', isPresent(apiKey));
this.API_KEY = apiKey;
}
query(q) {
let url = `https://api.giphy.com/v1/gifs/search?q=${q}&api_key=${this.API_KEY}&limit=10`;
return request(url);
}
}
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.loading {
background: #aaa;
display: block;
width: 300px;
height: 200px;
margin-bottom: 20px;
}
.loading:before {
content: "";
}
.animated-background {
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 1000px 104px;
position: relative;
}
@keyframes placeHolderShimmer{
0%{
background-position: -468px 0
}
100%{
background-position: 468px 0
}
}
li {
list-style: none;
}
<h1>Hello EmberFest!</h1>
<p>"Skeleton loading" with <code>ember-parachute</code> and <code>ember-concurrency</code>.</p>
<div class="search">
<form>
<input
class="u-full-width"
type="text"
value={{query}}
oninput={{action (mut query) value="target.value"
placeholder="Search giphy"}}
>
</form>
</div>
{{#giphy-loader query=query as |loader|}}
<div class="results">
<strong>Results:</strong>
{{#if loader.isRunning}}
<ul>
{{#each (repeat 10) as |empty|}}
<li class="loading animated-background">{{empty}}</li>
{{/each}}
</ul>
{{else}}
<ul>
{{#each loader.data as |d|}}
<li>
<img src="https://media.giphy.com/media/{{d.id}}/giphy.gif" width="300px">
</li>
{{/each}}
</ul>
{{/if}}
</div>
{{/giphy-loader}}
{{yield (hash
isRunning=fetchData.isRunning
data=results)
}}
{
"version": "0.12.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.12.0",
"ember-template-compiler": "2.12.0",
"ember-testing": "2.12.0",
"skeleton-css": "https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css"
},
"addons": {
"ember-data": "2.12.1",
"ember-ajax": "3.0.0",
"ember-parachute": "0.3.2",
"ember-concurrency": "0.8.10",
"ember-composable-helpers": "2.0.3"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment