1

I am trying to merge or basically perform an inner join on two datasets provided by https://jsonplaceholder.typicode.com/comments and https://jsonplaceholder.typicode.com/posts. The join would of course be using the PostId and id keys of both data sets respectively; however I am unsure of how to actually do this. I've added my codepen: https://codepen.io/gabedesigns/pen/qMGgxY?editors=1111 and I seem to be getting an error saying that I am missing '()' for my constructor. After figuring this out I will also need to search for posts with provided post ID and the comments corresponding the post. Perhaps I need nested for loops in order to make this work? I've tried to look up some other information on this and couldn't seem to find much. If there are any other resources I may have skipped over please don't be afraid to link it below. I saw a post on here already talking about "inner joins" with javascript instead of SQL, but this is where I ran into some problems. Here is some code:

function getResults() {

  const equijoin = (xs, ys, primary, foreign, sel) => {
   const ix = xs.reduce((ix, row) => ix.set(row[primary], row), new Map());
    return ys.map(row => sel(ix.get(row[foreign]), row));
  };

  const postData = fetch("https://jsonplaceholder.typicode.com/posts")
   .then(function(response) {
     return response.json();
  });

  const commentData = fetch("https://jsonplaceholder.typicode.com/comments")
   .then(function(response) {
    return response.json();
  });

  const result = equijoin(postData, commentData,"id", "postId", ({title, 
  body}, {name,body}) => ({title,body,name}));

}
G.Rose
  • 644
  • 7
  • 29
  • That was a solution posted on here from a different question. Not a 100% sure, but I think it’s the same as a select statement – G.Rose Sep 25 '18 at 00:14
  • can you post the question link ? – karthick Sep 25 '18 at 00:15
  • https://stackoverflow.com/questions/17500312/is-there-some-way-i-can-join-the-contents-of-two-javascript-arrays-much-like-i/17500836#17500836 – G.Rose Sep 25 '18 at 00:18
  • ({title, body}, {name,body}) this one is giving an error because body is considered as a duplicate parameter. trying moving these two to variables and then pass it in the callback – karthick Sep 25 '18 at 01:00
  • Yeah I tried to just remove one of the body tags and replace it with something else before, but wasn’t able to get it working – G.Rose Sep 25 '18 at 01:03
  • I turned it into id instead of body on one – G.Rose Sep 25 '18 at 01:04
  • Your code has other problems too. postData and commentData's values are promises it's not what you think. If you want to pass the result then you need to use promise.all and then read the response from there and then call equijoin – karthick Sep 25 '18 at 01:08

1 Answers1

4

There were a couple of problems here. I think you may have been running afoul of the async nature of fetch in trying to pass a promise into your sort function rather than waiting for it to resolve, gathering them up into a Promise.all batch is one way to handle this. Also as noted by someone in the comments you are using destructuring on two variables with the same name, the two easy solutions here are don't destructure or use an alias. Hope this helps

function getResults() {
const checkResult = res => res.ok ? res.json() : Promise.resolve({});
const joinMap = ({title, body:lbody}, {name,body:rbody}) => ({title,lbody, rbody,name});

const equiJoin = (xs, ys, primary, foreign, sel) => {
    const ix = xs.reduce(
      (ix, row) => ix.set(row[primary], row), new Map()
    );
    return ys.map(row => sel(ix.get(row[foreign]), row));
}
const posts = fetch("https://jsonplaceholder.typicode.com/posts")
  .then(checkResult);
  
const comments = fetch("https://jsonplaceholder.typicode.com/comments")
  .then(checkResult);

return Promise.all([posts, comments])
  .then(([postData, commentData]) => {
    const result = equiJoin(postData, commentData,"id", "postId", joinMap);
    console.log(result);
  })
  .catch(err => console.error(err));
}
button {
  background-color: white;
  color: black;
  border: 2px solid #555555;
  border-radius: 4px;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
}

button:hover {
  background-color: #555555;
  color: white;
}

input {
  width: 20vw;
  height: 10vh;
  padding: 0.5%;
  border-radius: 4px;
  border: 1px solid black;
}

#results {
  position: absolute;
  border: 1px solid gray;
  height: 60vh;
  width: 60vw;
  left: 20vw;
  top: 10vw;
}
<input type="text" id="postIDinput" placeholder="Post ID" required="true"></input>
<button type="submit" onclick="getResults()">Submit</button>

<div id="results"></div>
D Lowther
  • 1,609
  • 1
  • 9
  • 16
  • Pretty spot on to what I needed. Thank you. I just assumed the promises would resolve the data into JSON since the data is JSON. Another lesson on never assume haha. Do you have any resources you would recommend so I could learn more in depth about why I was wrong? – G.Rose Sep 25 '18 at 01:25
  • they are a bit dry, but when I first switched to fetch and promises from the older jQuery or XMLHttpRequest solutions the articles [`using fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) and [`using promises`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) from MDN were both really helpful. – D Lowther Sep 25 '18 at 12:25
  • Thank you, that's what I am coming from so fetch is a bit weird haha. Thank you again – G.Rose Sep 25 '18 at 14:13