JSFiddle - React, Tailwind, and code Playground
by knrm720
HTML
<script src="https://cdn.jsdelivr.net/kefir/3.1.0/kefir.js"></script>
<h3>GitHub repos search</h3>
<p>To see a error, dissable internet connection, or just play with it for a while and you'll <a target="_blank" href="https://developer.github.com/v3/#rate-limiting">exceed GitHub API rate limit</a>.</p>
<p>Also open up the DevTools to see that requests in which we not interested any more are being canceled.</p>
<input type="text" id="search-query" placeholder="search..." />
<div id="search-result"></div>
JavaScript
// General utility functions
// Accepts `jQuery.ajax` options.
// Returns a Propery that will contain single value or error.
// The request is send at the moment the property gets a subscriber,
// and if it loses all subscribers before the response, the request will be canceled.
function ajax(options) {
return Kefir.stream(function(emitter) {
var jqXHR = $.ajax(options);
jqXHR.done(emitter.emit);
jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
emitter.error(jqXHR.status === 0 ? 'Connection problem' : jqXHR.responseText);
});
return function() {
jqXHR.abort();
}
}).take(1).takeErrors(1).toProperty();
}
// Returns a Property containig current input value
function inputValue(input) {
function getValue() {
return input.value;
}
return Kefir
.fromEvents(input, 'input', getValue)
.toProperty(getValue);
}
// Less general utility functions
function search(queryStr) {
return ajax({
url: 'https://api.github.com/search/repositories',
data: {
q: queryStr,
sort: 'stars',
order: 'desc'
}
}).map(function(data) {
return data.items;
});
}
// Pure render functions
function renderLoading() {
return '<span>loading...</span>';
}
function renderError(error) {
return '<span style="color:red">' + error + '</span>';
}
function renderResults(items) {
// Who needs React, when we have concatination?
return '<ul>' + items.map(function(item) {
return '<li><a target="_blank" href="' + item.html_url + '">' + item.full_name + '</a> (' + item.stargazers_count + ')</li>';
}).join('') + '</ul>';
}
// Main app code
var searchQuery = inputValue(document.querySelector('#search-query'));
var searchResult = searchQuery.flatMapLatest(function(queryStr) {
return queryStr.length > 0 ? search(queryStr) : Kefir.constant([]);
});
var resultHtml = Kefir.merge([
searchQuery.map(renderLoading),
searchResult.map(renderResults),
...