Josh R. answered 05/20/21
Full-Stack Ruby/Javascript Developer
Hi Jeremy,
In the case that you can't control what the API is returning, a solution would be to create and attach your own generator to the object you receive from your API call. Lets take a look at what that looks like for your response object.
First lets access our channels object in the response. After we JSON.parse it we can
** There was an issue with syntax highlighting, FYI **
This is just a destructuring assignment. We could have written it like this
I just think the first one looks cleaner.
Now let's define our generator function. A generator function is a special function in JavaScript that allows us to iterate over an Iterable. Basically, an Iterable is a special kind of object that responds to a .next() function call and returns out the 'next' object in the sequence. Here is a simple generator function we can use to solve your issue.
Ok, there's a couple of things going on here. First off, you may notice there is an asterisk after the function keyword. That is to denote to JavaScript that we are creating a generator. Inside our generator we have a simple for/of loop. The for/of loop is designed to easily iterate over Iterable objects. Interestingly enough, objects, that is to say these {}, in JavaScript are not iterable by default. That's kinda why we have to build this thing in the first place. However, arrays are iterable by default! So the call to Object.keys() returns us an Array, so that's why we can use the for/of loop here.
Our generator function is iterating over all the keys in our object, and is 'yielding' out the result of
this[key][0];
This yield keyword enables us to do some pretty cool stuff, but that may be beyond the scope of this question. All you really have to know is it acts sort of like a return statement within our context. Also, we go ahead and return out the first element of the array produced by
this[key]
This is because every result you provided in your example data had only one element.
So let's put all these parts together. In order to make our response object iterable we need to assign our generator function to a property called [Symbol.iterator]. Here is what that looks like
Then, to get your data, all you have to do is execute
let data = [...channels]
This will produce
[
{
channel: '1620184778889x527731420801269760',
timetoken: '16204064644032062',
message: { content: '44444444444', sender: 'Jeremy' },
messageType: null,
uuid: '1617237881603x986210451354598100'
},
{
channel: '1618599897203x154294096401530880',
timetoken: '16203351496721278',
message: { content: 'fffffffdd', sender: 'Jeremy' },
messageType: null,
uuid: '1617237881603x986210451354598100'
},
{
channel: '1618613571551x955443898854408200',
timetoken: '16204261556065826',
message: { content: '78777', sender: 'Jeremy' },
messageType: null,
uuid: '1617237881603x986210451354598100'
}
]
Those three dots are called a spread operator or spread syntax. All this does is aggregate each piece of channel data in a nice neat array by using what was yielded from our generator.
From here, we can use a template literal to build your HTML. A quick example might look something like this
function template({
channel,
timetoken,
message: {
content,
sender
}
}){
return `
<div>${channel}</div>
<div>${timetoken}</div>
<div>${content}</div>
<div>${sender}</div>
`
}
And to use this function we could do something like this
That should about wrap it up. This answer was a little long, and some of the concepts are not beginner friendly, but I encourage you to explore the areas you aren't familiar with and please, do not hesitate to hit me up with any questions!
I hope this helps,
Josh