wikipedia api
In this tutorial, we’ll build a UI using Wikipedia’s public search API along with some JavaScript + RamdaJS.
在本教程中,我们将使用Wikipedia的公共搜索API以及一些JavaScript + RamdaJS来构建UI。
入门 (Getting Started)
Here’s the GitHub link and Codesandbox link. Open your terminal and pick a directory to clone it.
这是GitHub链接和Codesandbox链接 。 打开您的终端并选择一个目录来克隆它。
git clone [https://github.com/yazeedb/ramda-wikipedia-search](https://github.com/yazeedb/ramda-wikipedia-search)
cd ramda-wikipedia-search
yarn install (or npm install)
The master
branch has the finished project, so check out the start
branch if you wish to code along.
master
分支具有完成的项目,因此如果您希望继续编码,请签出start
分支。
git checkout start
git checkout start
And start the project!
并开始项目!
npm start
npm start
Your browser should automatically open localhost:1234.
您的浏览器应自动打开localhost:1234 。
获取输入值 (Getting the Input Value)
Here’s the initial app.
这是最初的应用程序。
To capture the user’s input as they type, our input
element needs an event listener.
为了在键入时捕获用户的输入,我们的input
元素需要一个事件侦听器。
Your src/index.js
file is already hooked up and ready to go. You’ll notice we imported Bootstrap for styling.
您的src/index.js
文件已经连接好并可以使用了。 您会注意到我们导入了Bootstrap进行样式设置。
Let’s add a dummy event listener to get things going.
让我们添加一个虚拟事件侦听器以使事情进展。
import 'bootstrap/dist/css/bootstrap.min.css';
const inputElement = document.querySelector('input');
inputElement.addEventListener('keyup', (event) => {
console.log('value:', event.target.value);
});
We know event.target.value
's the standard way to access an input’s value. Now it shows the value.
我们知道event.target.value
是访问输入值的标准方法。 现在,它显示了值。
How can Ramda help us achieve the following?
Ramda如何帮助我们实现以下目标?
Grab
event.target.value
抓住
event.target.value
- Trim the output (strip leading/trailing whitespace) 修剪输出(带状前导/尾随空白)
Default to empty string if
undefined
如果
undefined
默认为空字符串
The pathOr
function can actually handle the first and third bullet points. It takes three parameters: the default, the path, and the data.
pathOr
函数实际上可以处理第一个和第三个项目符号点。 它包含三个参数:默认值,路径和数据。
So the following works perfectly
所以以下完美地工作
import { pathOr } from 'ramda';
const getInputValue = pathOr('', ['target', 'value']);
If event.target.value
is undefined
, we’ll get an empty string back!
如果event.target.value
undefined
,我们将返回一个空字符串!
Ramda also has a trim
function, so that solves our whitespace issue.
Ramda还具有trim
功能,因此可以解决我们的空白问题。
import { pathOr, trim } from 'ramda';
const getInputValue = (event) => trim(pathOr('', ['target', 'value'], event));
Instead of nesting those functions, let’s use pipe
. See my article on pipe if it’s new to you.
让我们使用pipe
代替嵌套这些函数。 如果您不熟悉它,请参阅我在管道上的文章 。
import { pathOr, pipe, trim } from 'ramda';
const getInputValue = pipe(
pathOr('', ['target', 'value']),
trim
);
We now have a composed function that takes an event
object, grabs its target.value
, defaults to ''
, and trims it.
现在,我们有了一个组合函数,该函数接受一个event
对象,获取其target.value
,默认为''
并对其进行修剪。
Beautiful.
美丽。
I recommend storing this in a separate file. Maybe call it getInputValue.js
and use the default export syntax.
我建议将其存储在单独的文件中。 也许将其称为getInputValue.js
并使用默认的导出语法。
获取Wikipedia URL (Getting the Wikipedia URL)
As of this writing, Wikipedia’s API search URL is https://en.wikipedia.org/w/api.php?origin=*&action=opensearch&search=
撰写本文时,Wikipedia的API搜索URL为https://en.wikipedia.org/w/api.php?origin=*&action=opensearch&search=
For an actual search, just append a topic. If you need bears, for example, the URL looks like this:
对于实际搜索,只需附加一个主题。 例如,如果您需要熊,则URL如下所示:
https://en.wikipedia.org/w/api.php?origin=*&action=opensearch&search=bears
https://zh.wikipedia.org/w/api.php?origin=*&action=opensearch&search=bears
We’d like a function that takes a topic and returns the full Wikipedia search URL. As the user types we build the URL based off their input.
我们想要一个带有主题并返回完整Wikipedia搜索URL的函数。 当用户键入内容时,我们将根据他们的输入来构建URL。
Ramda’s concat
works nicely here.
Ramda的concat
在这里效果很好。
import { concat } from 'ramda';
const getWikipediaSearchUrlFor = concat(
'https://en.wikipedia.org/w/api.php?origin=*&action=opensearch&search='
);
concat
, true to its name, concatenates strings and arrays. It’s curried so providing the URL as one argument returns a function expecting a second string. See my article on currying if it’s new!
concat
,其名称真实,连接字符串和数组。 它经过咖喱处理,因此提供URL作为一个参数会返回一个函数,该函数需要第二个字符串。 请参阅我关于currying的文章,如果它是新的!
Put that code into a module called getUrl.js
.
将该代码放入名为getUrl.js
的模块中。
Now let’s update index.js
. Import our two new modules, along with pipe
and tap
from Ramda.
现在让我们更新index.js
。 从Ramda导入我们的两个新模块以及pipe
和tap
。
import 'bootstrap/dist/css/bootstrap.min.css';
import { pipe, tap } from 'ramda';
import getInputValue from './getInputValue';
import getUrl from './getUrl';
const makeUrlFromInput = pipe(
getInputValue,
getUrl,
tap(console.warn)
);
const inputElement = document.querySelector('input');
inputElement.addEventListener('keyup', makeUrlFromInput);
This new code’s constructing our request URL from the user’s input and logging it via tap
.
这个新代码根据用户的输入来构造我们的请求URL并通过tap
对其进行记录。
Check it out.
看看这个。

发出AJAX请求 (Making the AJAX Request)
Next step is mapping that URL to an AJAX request and collecting the JSON response.
下一步是将该URL映射到AJAX请求并收集JSON响应。
Replace makeUrlFromInput
with a new function, searchAndRenderResults
.
更换makeUrlFromInput
的一项新功能, searchAndRenderResults
。
const searchAndRenderResults = pipe(
getInputValue,
getUrl,
(url) =>
fetch(url)
.then((res) => res.json())
.then(console.warn)
);
Don’t forget to change your event listener too!
不要忘记也更改您的事件监听器!
inputElement.addEventListener('keyup', searchAndRenderResults);
Here’s our result.
这是我们的结果。

制作结果组件 (Making a Results Component)
Now that we have JSON, let’s create a component that pretties it up.
现在我们有了JSON,让我们创建一个漂亮的组件。
Add Results.js
to your directory.
将Results.js
添加到您的目录。
Look back at our Wikipedia search JSON response. Note its shape. It’s an array with the following indices:
回头看看我们的Wikipedia搜索JSON响应。 注意它的形状。 这是具有以下索引的数组:
- Query (what you searched for) 查询(搜索内容)
- Array of result names 结果名称数组
- Array of summaries 摘要数组
- Array of links to results 指向结果的链接数组
Our component can take an array of this shape and return a nicely formatted list. Through ES6 array destructuring, we can use that as our function signature.
我们的组件可以采用此形状的数组,并返回格式正确的列表。 通过ES6数组解构,我们可以将其用作函数签名。
Edit Results.js
编辑Results.js
export default ([query, names, summaries, links]) => `
<h2>Searching for "${query}"</h2>
<ul class="list-group">
${names.map(
(name, index) => `
<li class="list-group-item">
<a href=${links[index]} target="_blank">
<h4>${name}</h4>
</a>
<p>${summaries[index]}</p>
</li>
`
)}
</ul>
`;
Let’s go step by step.
让我们一步一步走。
It’s a function that takes an array of our expected elements:
query
,names
,summaries
, andlinks
.这个函数需要一系列我们期望的元素:
query
,names
,summaries
和links
。Using ES6 template literals, it returns an HTML string with a title and a list.
使用ES6模板文字 ,它返回带有标题和列表HTML字符串。
Inside the
<ul>
we mapnames
to<li>
tags, so one for each.在
<ul>
内部,我们将names
映射到<li>
标记,因此每个标记一个。Inside those are
<a>
tags pointing to each result’s link. Each link opens in a new tab.在其中的
<a>
标记指向每个结果的链接。 每个链接在新选项卡中打开。- Below the link is a paragraph summary. 链接下方是段落摘要。
Import this in index.js
and use it like so:
将其导入index.js
并按如下方式使用:
// ...
import Results from './Results';
// ...
const searchAndRenderResults = pipe(
getInputValue,
getUrl,
(url) =>
fetch(url)
.then((res) => res.json())
.then(Results)
.then(console.warn)
);
This passes the Wikipedia JSON to Results
and logs the result. You should be seeing a bunch of HTML in your DevTools console!
这会将Wikipedia JSON传递给Results
并记录结果。 您应该在DevTools控制台中看到大量HTML!

All that’s left is to render it to the DOM. A simple render
function should do the trick.
剩下的就是将其呈现给DOM。 一个简单的render
函数应该可以解决问题。
const render = (markup) => {
const resultsElement = document.getElementById('results');
resultsElement.innerHTML = markup;
};
Replace console.warn
with the render
function.
用render
函数替换console.warn
。
const searchAndRenderResults = pipe(
getInputValue,
getUrl,
(url) =>
fetch(url)
.then((res) => res.json())
.then(Results)
.then(render)
);
And check it out!
并检查出来!
Each link should open in a new tab.
每个链接都应在新标签中打开。
删除那些奇怪的逗号 (Removing Those Weird Commas)
You may have noticed something off about our fresh UI.
您可能已经注意到有关我们的新版UI的一些问题。

It has extra commas! Why??
它有多余的逗号! 为什么??
模板文字 (Template Literals)
It’s all about how template literals join things. If you stick in an array, it’ll join it using the toString()
method.
这都是关于模板文字如何连接事物的。 如果坚持使用数组,它将使用toString()
方法将其加入。
See how this becomes joined?
看看这是如何加入的?
const joined = [1, 2, 3].toString();
console.log(joined);
// 1,2,3
console.log(typeof joined);
// string
Template literals do that if you put arrays inside of them.
如果将模板放在其中,则模板文字会这样做。
const nums = [1, 2, 3];
const msg = `My favorite nums are ${nums}`;
console.log(msg);
// My favorite nums are 1,2,3
You can fix that by joining the array without commas. Just use an empty string.
您可以通过加入不带逗号的数组来解决此问题。 只需使用一个空字符串。
const nums = [1, 2, 3];
const msg = `My favorite nums are ${nums.join('')}`;
console.log(msg);
// My favorite nums are 123
Edit Results.js
to use the join
method.
编辑Results.js
以使用join
方法。
export default ([query, names, summaries, links]) => `
<h2>Searching for "${query}"</h2>
<ul class="list-group">
${names
.map(
(name, index) => `
<li class="list-group-item">
<a href=${links[index]} target="_blank">
<h4>${name}</h4>
</a>
<p>${summaries[index]}</p>
</li>
`
)
.join('')}
</ul>
`;
Now your UI’s much cleaner.
现在,您的UI更加整洁。

修复小错误 (Fixing a Little Bug)
I found a little bug while building this. Did you notice it?
构建此程序时,我发现了一个小错误。 你注意到了吗?

Emptying the input
throws this error.
清空input
将引发此错误。

That’s because we’re sending an AJAX request without a search topic. Check out the URL in your Network tab.
这是因为我们发送的AJAX请求中没有搜索主题。 在“网络”标签中查看网址。

That link points to a default HTML page. We didn’t get JSON back because we didn’t specify a search topic.
该链接指向默认HTML页面。 我们没有返回JSON,因为我们没有指定搜索主题。
To prevent this from happening we can avoid sending the request if the input
's empty.
为了防止这种情况的发生,我们可以避免在input
空的情况下发送请求。
We need a function that does nothing if the input
's empty, and does the search if it’s filled.
我们需要一个函数,如果input
空,则不执行任何操作,如果input
空, 则执行搜索 。
Let’s first create a function called doNothing
. You can guess what it looks like.
首先创建一个名为doNothing
的函数。 您可以猜测它的外观。
const doNothing = () => {};
This is better known as noOp
, but I like doNothing
in this context.
这就是众所周知的noOp
,但是在这种情况下我喜欢doNothing
。
Next remove getInputValue
from your searchAndRenderResults
function. We need a bit more security before using it.
接下来,从searchAndRenderResults
函数中删除getInputValue
。 使用它之前,我们需要更多的安全性。
const searchAndRenderResults = pipe(
getUrl,
(url) =>
fetch(url)
.then((res) => res.json())
.then(Results)
.then(render)
);
Import ifElse
and isEmpty
from Ramda.
从ifElse
导入ifElse
和isEmpty
。
import { ifElse, isEmpty, pipe, tap } from 'ramda';
Add another function, makeSearchRequestIfValid
.
添加另一个函数makeSearchRequestIfValid
。
const makeSearchRequestIfValid = pipe(
getInputValue,
ifElse(isEmpty, doNothing, searchAndRenderResults)
);
Take a minute to absorb that.
花一点时间吸收它。
If the input value’s empty, do nothing. Else, search and render the results.
如果输入值为空,则不执行任何操作。 否则,搜索并渲染结果。
You can gather that information just by reading the function. That’s expressive.
您只需阅读该功能即可收集该信息。 这就是表现。
Ramda’s isEmpty function works with strings, arrays, objects.
Ramda的isEmpty函数可用于字符串,数组,对象。

This makes it perfect to test our input value.
这使它非常适合测试我们的输入值。
ifElse
fits here because when isEmpty
returns true, doNothing
runs. Otherwise searchAndRenderResults
runs.
ifElse
适合这里,因为当isEmpty
返回true时, doNothing
运行。 否则, searchAndRenderResults
将运行。
Lastly, update your event handler.
最后,更新您的事件处理程序。
inputElement.addEventListener('keyup', makeSearchRequestIfValid);
And check the results. No more errors when clearing the input
!
并检查结果。 清除input
时不再有错误!

This tutorial was from my completely free course on Educative.io, Functional Programming Patterns With RamdaJS!
本教程来自我 完全免费的 课程 Educative.io, RamdaJS函数编程模式 !
Please consider taking/sharing it if you enjoyed this content.
如果您喜欢此内容,请考虑将其共享。
It’s full of lessons, graphics, exercises, and runnable code samples to teach you a basic functional programming style using RamdaJS.
它包含所有课程,图形,练习和可运行的代码示例,以教您使用RamdaJS的基本功能编程样式。
Thank you for reading ❤️
感谢您阅读❤️
翻译自: https://www.freecodecamp.org/news/how-to-build-wikipedias-api-search-with-ramdajs-b3c1a069d7af/
wikipedia api