WeeklyRandom #0
Tags: weeklyrandom, learning, github, javascript
Published: 2018-10-15 18:33:26

---
title: WeeklyRandom #0
published: true
tags: weeklyrandom, learning, github, javascript
canonical_url: https://nikol.as/blog/2018/10/weeklyrandom-0/
---

_Welcome to [**WeeklyRandom**](https://dev.to/t/weeklyrandom), a blog series in which I challenge myself to explore a random GitHub repository starred by me every week._

Let's get started. I'll need a way to retrieve a random GitHub repository starred by me. I found [this Gist](https://gist.github.com/derhuerst/19e0844796fa3b62e1e9567a1dc0b5a3) that shows how one can retrieve the starred repositories of a user.

```js
// https://gist.github.com/derhuerst/19e0844796fa3b62e1e9567a1dc0b5a3
const stars = (user) =>
	got(`https://api.github.com/users/${user}/starred`)
	.then((res) => JSON.parse(res.body))
	.then((starred) => starred.map((s) => ({
		  owner:       s.owner.login
		, repo:        s.name
		, description: s.description
		, language:    s.language
		, isFork:      false
		, stargazers:  s.stargazers_count
		, watchers:    s.watchers_count
})))
```

I am no JavaScript wizard 🧙 and do not know if the [`got`](https://github.com/sindresorhus/got) dependency is really necessary here. Let's keep it for now.

Problem: This only returns 30 repositories. Since the [GitHub API](https://developer.github.com/v3/) is paginated, I'll need to figure out a way to get the total number of pages before trying to get a random page and entry. I solved this by parsing the response headers which contained the following `Link`:

```
<https://api.github.com/user/13335308/starred?page=2>; rel="next", <https://api.github.com/user/13335308/starred?page=93>; rel="last"
```

Perfect. I can use `rel="last"` to generate a random page number between 1 and - in this case - 93. If I send a request for that page, the only thing left to do is to pick a random repository out of the returned 30.

This is the current script:

> Note: Updated on Oct 16, 2018 to reflect changes suggested by [u/ChucklefuckBitch](https://www.reddit.com/r/learnjavascript/comments/9onbd6/looking_for_feedback_on_a_script_to_get_a_random/e7vdm0t/) and [u/dulac91](https://www.reddit.com/r/learnjavascript/comments/9onbd6/looking_for_feedback_on_a_script_to_get_a_random/e7vky1a/). Thanks!

```js
// index.js

"use strict";

const got = require("got");

let user = process.argv.slice(2)[0];
let randomEntry = Math.floor(Math.random() * 30);
let lastPage = new RegExp(/(.*)page=(.*)>; rel=\"last\"/);

if (!user) {
  console.log("Usage: `node index.js username`");
  process.exit(1);
}

const getStars = (user, page) =>
  got(`https://api.github.com/users/${user}/starred?page=${page}`)
    .then((res) => JSON.parse(res.body))
    .then((starred) =>
      starred.map((s) => ({
        owner: s.owner.login,
        repo: s.name
      }))
    );

const getRandomPage = (user) =>
  got(`https://api.github.com/users/${user}/starred`)
    .then((res) =>
      res.headers.link
        .replace(lastPage, "$2")
    )
    .then((pages) => Math.floor(Math.random() * pages) + 1);

getRandomPage(user, randomEntry)
  .then((page) => getStars(user, page))
  .then((result) =>
    console.log("https://github.com/" + result[randomEntry].owner + "/" + result[randomEntry].repo)
  );
```

I'm pretty sure that this is a very inefficient way to do this, but it should get the job done. The whole purpose of this series is to learn something and to improve myself. And I definitely learned something about consuming the GitHub API and about [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) in JavaScript.

Let's try it:

```
node index.js vintagesucks
https://github.com/lgkonline/mavo-snippets

node index.js vintagesucks
https://github.com/simonepri/geo-maps

node index.js vintagesucks
https://github.com/genuinetools/apk-file
```

It works! 🎉

You can find the complete code on GitHub at [vintagesucks/random-starred-repository](https://github.com/vintagesucks/random-starred-repository). Pull requests with improvements are very welcome!

Until next week, when I'll check out my first [_WeeklyRandom_](https://dev.to/t/weeklyrandom) repository.