<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <div class="container">
    <div class="header">
      <h3>Who to follow</h3>
      <a href="#" class="refresh">Refresh</a>
    </div>
    <div class="suggestions">
      <div class="suggestion1">
        <img />
        <div class='user'>
          <h2 class="username">this will not be displayed</h2>
          <span class="close close1">x</span>
        </div>

      </div>
      <div class="suggestion2">
        <img />
        <div class='user'>
          <h2 class="username">this will not be displayed</h2>
          <span class="close close2">x</span>
        </div>
      </div>
      <div class="suggestion3">
        <img />
        <div class='user'>
          <h2 class="username">this will not be displayed</h2>
          <span class="close close3">x</span>
        </div>
      </div>
    </div>
    <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
  </div>
</body>

</html>
* {
  border: 0;
}

.container {
  width: 500px;
  margin: 40px auto;
}

.header {
  display: flex;
  flex-direction: row;
}

.header > a {
  padding: 20px;
}

.suggestions img {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  margin-right: 2rem;
}

.suggestions > div {
  display: flex;
  flex-direction: row;
}

.close {
  font-size: 2rem;
  margin-left: 3rem;
  padding: 15px;
  cursor: pointer;
}

.user {
  display: flex;
  flex-direction: row;
  width: 300px;
  justify-content: space-between;
}
const refreshButton = document.querySelector(".refresh");
const closeButton1 = document.querySelector(".close1");
const closeButton2 = document.querySelector(".close2");
const closeButton3 = document.querySelector(".close3");

const refreshClickStream$ = Rx.Observable.fromEvent(refreshButton, "click");
const closeStream1$ = Rx.Observable.fromEvent(closeButton1, "click");
const closeStream2$ = Rx.Observable.fromEvent(closeButton2, "click");
const closeStream3$ = Rx.Observable.fromEvent(closeButton3, "click");

const startRequest$ = Rx.Observable.of("https://randomuser.me/api/?results=50");
const refreshStream$ = refreshClickStream$.map(
  env => "https://randomuser.me/api/?results=50"
);
const getAnotherRequest$ = new Rx.Subject();

const requestStream$ = startRequest$
.merge(refreshStream$)
.merge(getAnotherRequest$);

const responseStream$ = requestStream$
.flatMap(url => Rx.Observable.ajax(url).map(e => e.response))
.publishReplay()
.refCount();

const getRandomUser = (function() {
  let _userArray = [];
  return function getUser(userList) {
    const { results } = userList;
    const user = results[Math.floor(Math.random() * results.length)];

    if (_userArray.includes(user)) {
      if (_userArray.length >= results.length) {
        _userArray = [];
        getAnotherRequest$.next("https://randomuser.me/api/?results=50");
      }
      return getUser(userList);
    }
    _userArray.push(user);
    return user;
  };
})();

function capitalize(s) {
  return s.charAt(0).toUpperCase() + s.slice(1);
}

function createSuggestionStream(responseStream, closeClickStream$) {
  return responseStream$
    .map(getRandomUser)
    .startWith(null)
    .merge(refreshClickStream$.map(ev => null))
    .merge(
    closeClickStream$.withLatestFrom(responseStream$, (ev, users) =>
                                     getRandomUser(users)
                                    )
  );
}

function generateSuggestion(ref, user) {
  const userEl = document.querySelector(ref);
  const imgEl = userEl.querySelector("img");
  if (user === null) {
    userEl.style.visibility = "hidden";
  } else {
    userEl.style.visibility = "visible";
    const usernameEl = userEl.querySelector(".username");
    usernameEl.textContent = `${capitalize(user.name.title)}. ${capitalize(
      user.name.last
    )}`;
    imgEl.src = user.picture.large;
  }
}

const suggestion1Stream$ = createSuggestionStream(
  responseStream$,
  closeStream1$
);
const suggestion2Stream$ = createSuggestionStream(
  responseStream$,
  closeStream2$
);
const suggestion3Stream$ = createSuggestionStream(
  responseStream$,
  closeStream3$
);

suggestion1Stream$.subscribe(user => generateSuggestion(".suggestion1", user));
suggestion2Stream$.subscribe(user => generateSuggestion(".suggestion2", user));
suggestion3Stream$.subscribe(user => generateSuggestion(".suggestion3", user));

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.