Display API results with JavaScript and HTML - javascript

First off, I'm very new to working with APIs at all. And English is not my first language. I've searched the web but came up short in finding exactly what I'm looking for, or at least I have not understood enough of what I read to understand how to alter and apply it to my situation.
I'm working with the Omdb API and the Giphy API, making a silly page. I'm using JavaScript and HTML.
At the end I want the page to display the search result of the user searching for a movie + on-topic gifs.
I've come so far that I have a result from both APIs. That's all good and well. What I don't know how to do is to from these results present, for example, just the movie titles and the .gif-files. My attempts at splitting the returned results have so far failed. Any suggestions? Below is my JavaScript code.
var form = document.getElementById('search-form');
form.addEventListener("submit", search);
function search(event) {
event.preventDefault();
document.getElementById("present_result").innerHTML = "";
if(this.elements.query.value === '') {
alert("Enter search word!");
} else {
var rawInputData = this.elements.query.value;
var fixedInputData = rawInputData.split(" ");
var inputData = encodeQueryData(fixedInputData);
var inputDataGif = encodeQueryDataGif(fixedInputData);
function encodeQueryData(data) {
let ret = [];
for (let d in data)
ret.push(encodeURIComponent(data[d]));
return ret.join('%20');
}
function encodeQueryDataGif(data) {
let ret = [];
for (let d in data)
ret.push(encodeURIComponent(data[d]));
return ret.join('+');
}
var omdbAPI = new XMLHttpRequest();
var gifAPI = new XMLHttpRequest();
var omdbURL = "http://www.omdbapi.com/?s=" + inputData + "&type=movie";
var gifURL = "http://api.giphy.com/v1/gifs/search?q=" + inputDataGif + "&limit=1&api_key=dc6zaTOxFJmzC";
omdbAPI.addEventListener("load", function() {
if (this.responseText === '{"Response":"False","Error":"Movie not found!"}')
{
alert("No result.");
} else {
var result = JSON.parse(this.responseText);
console.log(result);
result = JSON.stringify(result);
document.getElementById("present_result").innerHTML = result;
}
});
gifAPI.addEventListener("load", function() {
if (this.responseText === '{"Response":"False","Error":"Not found!"}')
{
alert("No Result.");
} else {
var result = JSON.parse(this.responseText);
console.log(result);
result = JSON.stringify(result);
document.getElementById("present_gif").innerHTML = result;
}
});
omdbAPI.open("get", omdbURL, true);
omdbAPI.send();
gifAPI.open("get", gifURL, true);
gifAPI.send();
}
}
And below the HTML.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Mashup test</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<!-- Form -->
<form action="" method="get" id="search-form" class="search-form">
Movie: <input type="text" name="query">
<button type="submit" id="submit">Search</button>
</form>
<!-- Result -->
<div id="present_result">
</div>
<div id="present_gif">
</div>
<script src="scripts.js"></script>
</body>
</html>
And here's a sample result from OMDb:
{
"Search": [{
"Title": "Titanic",
"Year": "1997",
"imdbID": "tt0120338",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BZDNiMjE0NDgtZWRhNC00YTlhLTk2ZjItZTQzNTU2NjAzNWNkXkEyXkFqcGdeQXVyNjUwNzk3NDc#._V1_SX300.jpg"
}, {
"Title": "Titanic II",
"Year": "2010",
"imdbID": "tt1640571",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTMxMjQ1MjA5Ml5BMl5BanBnXkFtZTcwNjIzNjg1Mw##._V1_SX300.jpg"
}, {
"Title": "Titanic: The Legend Goes On...",
"Year": "2000",
"imdbID": "tt0330994",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTg5MjcxODAwMV5BMl5BanBnXkFtZTcwMTk4OTMwMg##._V1_SX300.jpg"
}, {
"Title": "Titanic",
"Year": "1953",
"imdbID": "tt0046435",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTU3NTUyMTc3Nl5BMl5BanBnXkFtZTgwOTA2MDE3MTE#._V1_SX300.jpg"
}, {
"Title": "Raise the Titanic",
"Year": "1980",
"imdbID": "tt0081400",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTY5MTQwNzMxNV5BMl5BanBnXkFtZTcwMzkwOTMyMQ##._V1_SX300.jpg"
}, {
"Title": "The Legend of the Titanic",
"Year": "1999",
"imdbID": "tt1623780",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMjMxNDU5MTk1MV5BMl5BanBnXkFtZTgwMDk5NDUyMTE#._V1_SX300.jpg"
}, {
"Title": "The Chambermaid on the Titanic",
"Year": "1997",
"imdbID": "tt0129923",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMWUzYjgyNDEtNTAyMi00M2JjLTlhMzMtMDJmOGM1ZmYzNzY4XkEyXkFqcGdeQXVyMTA0MjU0Ng##._V1_SX300.jpg"
}, {
"Title": "In Search of the Titanic",
"Year": "2004",
"imdbID": "tt1719665",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTAzNjY0NDA2NzdeQTJeQWpwZ15BbWU4MDIwMzc1MzEx._V1_SX300.jpg"
}, {
"Title": "Titanic",
"Year": "1943",
"imdbID": "tt0036443",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTU2Njg4MDgxN15BMl5BanBnXkFtZTcwNzE4MjYyMQ##._V1_SX300.jpg"
}, {
"Title": "S.O.S. Titanic",
"Year": "1979",
"imdbID": "tt0079836",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTMwOTU5MDU0OV5BMl5BanBnXkFtZTcwMDc4OTYyMQ##._V1_SX300.jpg"
}],
"totalResults": "170",
"Response": "True"
}
And sample result from Giphy:
{
"data": [{
"type": "gif",
"id": "pWDH6fkHgGHza",
"slug": "titanic-leonardo-dicaprio-pWDH6fkHgGHza",
"url": "http://giphy.com/gifs/titanic-leonardo-dicaprio-pWDH6fkHgGHza",
"bitly_gif_url": "http://gph.is/Z15kA0",
"bitly_url": "http://gph.is/Z15kA0",
"embed_url": "http://giphy.com/embed/pWDH6fkHgGHza",
"username": "",
"source": "http://tomhiddles.tumblr.com/post/37231367662",
"rating": "g",
"content_url": "",
"source_tld": "tomhiddles.tumblr.com",
"source_post_url": "http://tomhiddles.tumblr.com/post/37231367662",
"is_indexable": 0,
"import_datetime": "2013-03-24 01:54:54",
"trending_datetime": "1970-01-01 00:00:00",
"images": {
"fixed_height": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/200.gif",
"width": "513",
"height": "200",
"size": "271598",
"mp4": "http://media0.giphy.com/media/pWDH6fkHgGHza/200.mp4",
"mp4_size": "19808",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/200.webp",
"webp_size": "392604"
},
"fixed_height_still": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/200_s.gif",
"width": "513",
"height": "200"
},
"fixed_height_downsampled": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/200_d.gif",
"width": "513",
"height": "200",
"size": "530508",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/200_d.webp",
"webp_size": "196204"
},
"fixed_width": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/200w.gif",
"width": "200",
"height": "78",
"size": "65057",
"mp4": "http://media0.giphy.com/media/pWDH6fkHgGHza/200w.mp4",
"mp4_size": "24950",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/200w.webp",
"webp_size": "74208"
},
"fixed_width_still": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/200w_s.gif",
"width": "200",
"height": "78"
},
"fixed_width_downsampled": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/200w_d.gif",
"width": "200",
"height": "78",
"size": "100970",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/200w_d.webp",
"webp_size": "37622"
},
"fixed_height_small": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/100.gif",
"width": "256",
"height": "100",
"size": "271598",
"mp4": "http://media0.giphy.com/media/pWDH6fkHgGHza/100.mp4",
"mp4_size": "170265",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/100.webp",
"webp_size": "98852"
},
"fixed_height_small_still": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/100_s.gif",
"width": "256",
"height": "100"
},
"fixed_width_small": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/100w.gif",
"width": "100",
"height": "39",
"size": "65057",
"mp4": "http://media0.giphy.com/media/pWDH6fkHgGHza/100w.mp4",
"mp4_size": "45670",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/100w.webp",
"webp_size": "23380"
},
"fixed_width_small_still": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/100w_s.gif",
"width": "100",
"height": "39"
},
"downsized": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy.gif",
"width": "500",
"height": "195",
"size": "1006467"
},
"downsized_still": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy_s.gif",
"width": "500",
"height": "195"
},
"downsized_large": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy.gif",
"width": "500",
"height": "195",
"size": "1006467"
},
"downsized_medium": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy.gif",
"width": "500",
"height": "195",
"size": "1006467"
},
"original": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy.gif",
"width": "500",
"height": "195",
"size": "1006467",
"frames": "12",
"mp4": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy.mp4",
"mp4_size": "84279",
"webp": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy.webp",
"webp_size": "378130"
},
"original_still": {
"url": "http://media0.giphy.com/media/pWDH6fkHgGHza/giphy_s.gif",
"width": "500",
"height": "195"
},
"looping": {
"mp4": "http://media.giphy.com/media/pWDH6fkHgGHza/giphy-loop.mp4"
},
"preview": {
"mp4": "http://media3.giphy.com/media/pWDH6fkHgGHza/giphy-preview.mp4",
"mp4_size": "44332",
"width": "326",
"height": "126"
},
"downsized_small": {
"mp4": "http://media3.giphy.com/media/pWDH6fkHgGHza/giphy-downsized-small.mp4",
"mp4_size": "116662"
}
}
}],
"meta": {
"status": 200,
"msg": "OK",
"response_id": "5887622069432538bfa2a521"
},
"pagination": {
"total_count": 11258,
"count": 1,
"offset": 0
}
}

Both APIs return you a JSON object.
A json object is generally construct like so:
{
"property1": "value1",
"property2": "value2"
"property_array": ["arrayValue1", "arrayValue2"],
"property_object": {
"propertyA": "valueA",
"attributeB": "valueB"
}
}
So let use OMDb (for example):
to access the results, you need to acces the "Search" attribute :
var entries = result.Search;
Then, you need to "loop" on each property of the Search object (whitch is also an object) :
to do so, you can use a for...in loop:
for(var entry_key in entries) {
// control that property is own by the object (not prototype)
if(entries.hasOwnProperty(entry_key)) {
// do whatever you want with the entry
// To access the entry, use this notation:
var entry = entries[entry_key];
// to stay with OMDb example, this should be:
var movie_title = entry.Title;
}
}
var results = {
"Search": [{
"Title": "Titanic",
"Year": "1997",
"imdbID": "tt0120338",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BZDNiMjE0NDgtZWRhNC00YTlhLTk2ZjItZTQzNTU2NjAzNWNkXkEyXkFqcGdeQXVyNjUwNzk3NDc#._V1_SX300.jpg"
}, {
"Title": "Titanic II",
"Year": "2010",
"imdbID": "tt1640571",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTMxMjQ1MjA5Ml5BMl5BanBnXkFtZTcwNjIzNjg1Mw##._V1_SX300.jpg"
}, {
"Title": "Titanic: The Legend Goes On...",
"Year": "2000",
"imdbID": "tt0330994",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTg5MjcxODAwMV5BMl5BanBnXkFtZTcwMTk4OTMwMg##._V1_SX300.jpg"
}, {
"Title": "Titanic",
"Year": "1953",
"imdbID": "tt0046435",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTU3NTUyMTc3Nl5BMl5BanBnXkFtZTgwOTA2MDE3MTE#._V1_SX300.jpg"
}, {
"Title": "Raise the Titanic",
"Year": "1980",
"imdbID": "tt0081400",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTY5MTQwNzMxNV5BMl5BanBnXkFtZTcwMzkwOTMyMQ##._V1_SX300.jpg"
}, {
"Title": "The Legend of the Titanic",
"Year": "1999",
"imdbID": "tt1623780",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMjMxNDU5MTk1MV5BMl5BanBnXkFtZTgwMDk5NDUyMTE#._V1_SX300.jpg"
}, {
"Title": "The Chambermaid on the Titanic",
"Year": "1997",
"imdbID": "tt0129923",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMWUzYjgyNDEtNTAyMi00M2JjLTlhMzMtMDJmOGM1ZmYzNzY4XkEyXkFqcGdeQXVyMTA0MjU0Ng##._V1_SX300.jpg"
}, {
"Title": "In Search of the Titanic",
"Year": "2004",
"imdbID": "tt1719665",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTAzNjY0NDA2NzdeQTJeQWpwZ15BbWU4MDIwMzc1MzEx._V1_SX300.jpg"
}, {
"Title": "Titanic",
"Year": "1943",
"imdbID": "tt0036443",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTU2Njg4MDgxN15BMl5BanBnXkFtZTcwNzE4MjYyMQ##._V1_SX300.jpg"
}, {
"Title": "S.O.S. Titanic",
"Year": "1979",
"imdbID": "tt0079836",
"Type": "movie",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTMwOTU5MDU0OV5BMl5BanBnXkFtZTcwMDc4OTYyMQ##._V1_SX300.jpg"
}],
"totalResults": "170",
"Response": "True"
};
var movies_list = document.getElementById('movies-list');
var entries = results.Search;
for(var entry_key in entries) {
// control that property is own by the object (not prototype)
if(entries.hasOwnProperty(entry_key)) {
// do whatever you want with the entry
// To access the entry, use this notation:
var entry = entries[entry_key];
// to stay with OMDb example, this should be:
var movie_line = '<p><strong>Title:</strong> '
+ entry.Title + ' (year: ' + entry.Year + ')</p>';
movies_list.innerHTML += movie_line;
}
}
<div id="movies-list">
</div>

Related

How can I take the data from choiceSet in adaptive cards

I want the data (i.e value inside choices array) inside the red choiseSet when selected and clicked on the btn, I kept an image and added action submit as action.submit as that's my usecase, I am pretty much confused how I can do that, Here's the card payload
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.2",
"body": [
{
"type": "Input.ChoiceSet",
"id": "myColor2",
"style": "expanded",
"value": "1",
"choices": [
{
"title": "Red",
"value": "1"
}
]
},
{
"type": "Image",
"altText": "it's a image",
"url": "https://media.istockphoto.com/vectors/bhutanese-ngultrum-btn-vector-id1304476894",
"width": "100px",
"height": "100px",
"horizontalAlignment": "Left",
"selectAction": {
"type": "Action.Submit",
"id": "btn",
"title": "btn"
}
}
]
}
Once submitted by clicking on the icon, the bot should receive an activity of type message but with no text. The data you want is in the value property.
{
"activity": {
"channelData": {
"postBack": true,
"clientActivityID": "<REMOVED>",
"clientTimestamp": "2022-04-05T18:43:17.348Z"
},
"type": "message",
"value": {
"myColor2": "1"
},
"channelId": "emulator",
"from": {
"id": "<REMOVED>",
"name": "",
"role": "user"
},
"locale": "en-us",
"localTimestamp": "2022-04-05T11:43:17-07:00",
"localTimezone": "America/Los_Angeles",
"timestamp": "2022-04-05T18:43:17.408Z",
"id": "<REMOVED>",
"recipient": {
"id": "<REMOVED>",
"name": "Bot",
"role": "bot"
},
"conversation": {
"id": "<REMOVED>"
},
"serviceUrl": "http://localhost:3212"
},
"id": "<REMOVED>",
"timestamp": 1649184197408
}

Strapi.io filter data by date

I'm trying to deep filter API response from Strapi backend from a custom controller with entityService, but seems like I'm doing something wrong.
According to the documentation:
Strapi filter data
I can have multiple conditions there.
Strapi Version: 4.0.0
Operating System: macOS
Database: postgresql 14
Node Version: v14.17.6
NPM Version: 7.21.1
Yarn Version: 1.22.17
My controller code:
"use strict";
/**
* occasion controller
*/
const { createCoreController } = require("#strapi/strapi").factories;
const date = new Date().toLocaleString("en-US", {
timeZone: "America/Los_Angeles",
});
const dateClean = date.slice(0, 10).split("/");
const dateISOCompat = [dateClean[2], dateClean[0], dateClean[1]].join("-");
module.exports = createCoreController(
"api::occasion.occasion",
({ strapi }) => ({
async find(ctx) {
const { query } = ctx.params;
const entity = await strapi.entityService.findMany(
"api::occasion.occasion",
{
...query,
populate: {
image: true,
button: true,
category: true,
},
filters: {
$and: [
{
publishedAt: {
$notNull: true,
},
$and: [
{
category: {
startDate: {
$lt: dateISOCompat,
},
},
category: {
endDate: {
$gt: dateISOCompat,
},
},
},
],
},
],
},
}
);
return entity;
},
})
);
Date comparison should work I think, my assumption that something wrong with the syntax of filter deep nested conditions.
I still can get data from the API endpoint, but it didn't check for the date range...
My response looks like this:
[
{
"id": 1,
"title": "Are you choosing a cake for the most important event in your life?",
"subtitle": "",
"createdAt": "2021-12-09T23:49:24.518Z",
"updatedAt": "2021-12-30T20:59:28.264Z",
"publishedAt": "2021-12-30T20:59:28.261Z",
"image": {
"id": 10,
"name": "WeddingDate.jpg",
"alternativeText": "WeddingDate.jpg",
"caption": "WeddingDate.jpg",
"width": 2000,
"height": 1335,
"formats": {
"large": {
"ext": ".jpg",
"url": "/uploads/large_Wedding_Date_6c9d20762c.jpg",
"hash": "large_Wedding_Date_6c9d20762c",
"mime": "image/jpeg",
"name": "large_WeddingDate.jpg",
"path": null,
"size": 125.61,
"width": 1000,
"height": 668
},
"small": {
"ext": ".jpg",
"url": "/uploads/small_Wedding_Date_6c9d20762c.jpg",
"hash": "small_Wedding_Date_6c9d20762c",
"mime": "image/jpeg",
"name": "small_WeddingDate.jpg",
"path": null,
"size": 43.24,
"width": 500,
"height": 334
},
"medium": {
"ext": ".jpg",
"url": "/uploads/medium_Wedding_Date_6c9d20762c.jpg",
"hash": "medium_Wedding_Date_6c9d20762c",
"mime": "image/jpeg",
"name": "medium_WeddingDate.jpg",
"path": null,
"size": 79.71,
"width": 750,
"height": 501
},
"thumbnail": {
"ext": ".jpg",
"url": "/uploads/thumbnail_Wedding_Date_6c9d20762c.jpg",
"hash": "thumbnail_Wedding_Date_6c9d20762c",
"mime": "image/jpeg",
"name": "thumbnail_WeddingDate.jpg",
"path": null,
"size": 12.95,
"width": 234,
"height": 156
}
},
"hash": "Wedding_Date_6c9d20762c",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 383.44,
"url": "/uploads/Wedding_Date_6c9d20762c.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2021-12-09T19:34:37.053Z",
"updatedAt": "2021-12-09T19:34:37.053Z"
},
"button": {
"id": 1,
"text": "Order Now",
"buttonURL": "/products/",
"style": "Fill"
},
"category": {
"id": 1,
"name": "Regular Occasions",
"startDate": "2022-01-01",
"endDate": "2024-12-31",
"createdAt": "2021-12-09T23:49:59.083Z",
"updatedAt": "2021-12-09T23:56:21.637Z",
"publishedAt": "2021-12-09T23:55:11.891Z"
}
},
{
"id": 2,
"title": "Make your birthday unforgettable and bright!",
"subtitle": "",
"createdAt": "2021-12-09T23:53:15.734Z",
"updatedAt": "2021-12-22T22:06:15.962Z",
"publishedAt": "2021-12-09T23:54:55.136Z",
"image": {
"id": 3,
"name": "birthday_hero.jpg",
"alternativeText": "birthday_hero.jpg",
"caption": "birthday_hero.jpg",
"width": 1600,
"height": 1066,
"formats": {
"large": {
"ext": ".jpg",
"url": "/uploads/large_birthday_hero_af457271ec.jpg",
"hash": "large_birthday_hero_af457271ec",
"mime": "image/jpeg",
"name": "large_birthday_hero.jpg",
"path": null,
"size": 56.99,
"width": 1000,
"height": 666
},
"small": {
"ext": ".jpg",
"url": "/uploads/small_birthday_hero_af457271ec.jpg",
"hash": "small_birthday_hero_af457271ec",
"mime": "image/jpeg",
"name": "small_birthday_hero.jpg",
"path": null,
"size": 20.62,
"width": 500,
"height": 333
},
"medium": {
"ext": ".jpg",
"url": "/uploads/medium_birthday_hero_af457271ec.jpg",
"hash": "medium_birthday_hero_af457271ec",
"mime": "image/jpeg",
"name": "medium_birthday_hero.jpg",
"path": null,
"size": 37.06,
"width": 750,
"height": 500
},
"thumbnail": {
"ext": ".jpg",
"url": "/uploads/thumbnail_birthday_hero_af457271ec.jpg",
"hash": "thumbnail_birthday_hero_af457271ec",
"mime": "image/jpeg",
"name": "thumbnail_birthday_hero.jpg",
"path": null,
"size": 6.63,
"width": 234,
"height": 156
}
},
"hash": "birthday_hero_af457271ec",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 108.92,
"url": "/uploads/birthday_hero_af457271ec.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2021-12-09T19:34:35.479Z",
"updatedAt": "2021-12-09T19:34:35.479Z"
},
"button": {
"id": 2,
"text": "Order Now",
"buttonURL": "/products/",
"style": "Fill"
},
"category": {
"id": 1,
"name": "Regular Occasions",
"startDate": "2022-01-01",
"endDate": "2024-12-31",
"createdAt": "2021-12-09T23:49:59.083Z",
"updatedAt": "2021-12-09T23:56:21.637Z",
"publishedAt": "2021-12-09T23:55:11.891Z"
}
},
{
"id": 3,
"title": "How to Express Words of Love on Father's Day?",
"subtitle": "",
"createdAt": "2021-12-10T00:01:49.722Z",
"updatedAt": "2021-12-22T22:06:10.665Z",
"publishedAt": "2021-12-10T00:13:18.089Z",
"image": {
"id": 15,
"name": "FathersDay.jpg",
"alternativeText": "FathersDay.jpg",
"caption": "FathersDay.jpg",
"width": 1600,
"height": 664,
"formats": {
"large": {
"ext": ".jpg",
"url": "/uploads/large_Fathers_Day_7020aae6a3.jpg",
"hash": "large_Fathers_Day_7020aae6a3",
"mime": "image/jpeg",
"name": "large_FathersDay.jpg",
"path": null,
"size": 22.33,
"width": 1000,
"height": 415
},
"small": {
"ext": ".jpg",
"url": "/uploads/small_Fathers_Day_7020aae6a3.jpg",
"hash": "small_Fathers_Day_7020aae6a3",
"mime": "image/jpeg",
"name": "small_FathersDay.jpg",
"path": null,
"size": 8.88,
"width": 500,
"height": 208
},
"medium": {
"ext": ".jpg",
"url": "/uploads/medium_Fathers_Day_7020aae6a3.jpg",
"hash": "medium_Fathers_Day_7020aae6a3",
"mime": "image/jpeg",
"name": "medium_FathersDay.jpg",
"path": null,
"size": 15.33,
"width": 750,
"height": 311
},
"thumbnail": {
"ext": ".jpg",
"url": "/uploads/thumbnail_Fathers_Day_7020aae6a3.jpg",
"hash": "thumbnail_Fathers_Day_7020aae6a3",
"mime": "image/jpeg",
"name": "thumbnail_FathersDay.jpg",
"path": null,
"size": 3.45,
"width": 245,
"height": 102
}
},
"hash": "Fathers_Day_7020aae6a3",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 41.41,
"url": "/uploads/Fathers_Day_7020aae6a3.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2021-12-10T00:13:06.981Z",
"updatedAt": "2021-12-10T00:13:06.981Z"
},
"button": {
"id": 3,
"text": "Order Now",
"buttonURL": "/products/",
"style": "Fill"
},
"category": {
"id": 3,
"name": "Father's Day",
"startDate": "2022-06-01",
"endDate": "2022-06-19",
"createdAt": "2021-12-10T00:03:52.295Z",
"updatedAt": "2021-12-10T00:03:53.286Z",
"publishedAt": "2021-12-10T00:03:53.283Z"
}
}
.........

How do I solve this task in javascript? [duplicate]

This question already has answers here:
How to groupBy array of objects based on properties in vanilla javascript
(2 answers)
Closed 2 years ago.
I got a json file that contains beer types like this:
{
"type": "Unifiltered",
"name": "Heineken Unfiltered",
"id": "XY",
"brand": "Heineken",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
},
My task is to group beers by brand:
My friend has a list of all the beers available in his pub, but it’s a huge mess.
He would like to see the beers grouped by brands.
My friend also told you that the Function should return an array of Brand > objects which contain the array of Beers of that Brand.
Example:
[{brand: Heineken, beers: [{...}, ...]}]"
const beers = [{
"type": "Unifiltered",
"name": "Heineken Unfiltered",
"id": "XY",
"brand": "Heineken",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
},
{
"type": "type",
"name": "name",
"id": "XY",
"brand": "EFES",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
},
{
"type": "type3",
"name": "name2",
"id": "XY",
"brand": "EFES",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
}];
var group = beers.reduce((r, a) => {
r[a. brand] = [...r[a. brand] || [], a];
return r;
}, {});
console.log("group", group);
i think its already answered here
let group = beers.reduce((r, a) => {
r[a. brand] = [...r[a. brand] || [], a];
return r;
}, {});
console.log("group", group);
Written in an easily readable format, using array.forEach() in place of shorthand functions:
let beers = [{
"type": "Unifiltered",
"name": "Heineken Unfiltered",
"id": "XY",
"brand": "Heineken",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
}];
let brands = [];
// Loop over all beers
beers.forEach((beer) => {
// Try to find beer brand in existing list of brand
let brand = brands.filter((brand) => brand.brand === beer.brand)[0];
if(brand) {
// If we find it, push the beer onto the beer property
brand.beers.push(beer);
} else {
// If we don't find it, create a new brand and push it onto brands
brand = {
brand: beer.brand,
beers: [beer]
}
brands.push(brand);
}
});
console.log(brands);
I think Grouping JSON by values can be useful. Using the group_by function and then its is just cleaning up the answer to get what you need.

Converting Json to Csv issue

I am trying to convert a JSON to CSV with JavaScript. The problem is I keep getting the error: Cannot convert undefined or null to object
at Function.keys.
I only want the 'features.attributes' keys and values from the data. I have no problem getting the keys but the values seems to be a problem. Any help wuld be appreciated.
json
{
"displayFieldName": "label",
"fieldAliases": {
"OBJECTID": "OBJECTID",
"label": "label",
"west": "west",
"east": "east",
"north": "north",
"south": "south",
"scale": "scale",
"title": "title",
"edition": "edition",
"available": "available",
"physHold": "physHold",
"primeMer": "primeMer",
"projection": "projection",
"publisher": "publisher",
"datePub": "datePub",
"color": "color",
"recId": "recId",
"note": "note",
"location": "location",
"bathLines": "bathLines",
"bathInterv": "bathInterv",
"instCallNo": "instCallNo",
"setTitle": "setTitle",
"sheetId": "sheetId",
"digita": "digita",
"titleAlt": "titleAlt",
"digHold": "digHold",
"miradorURL": "miradorURL",
"iiifURL": "iiifURL",
"Shape_Length": "Shape_Length",
"Shape_Area": "Shape_Area"
},
"geometryType": "esriGeometryPolygon",
"spatialReference": {
"wkid": 102100,
"latestWkid": 3857
},
"fields": [
{
"name": "OBJECTID",
"type": "esriFieldTypeOID",
"alias": "OBJECTID"
},
{
"name": "label",
"type": "esriFieldTypeString",
"alias": "label",
"length": 50
},
{
"name": "west",
"type": "esriFieldTypeDouble",
"alias": "west"
},
{
"name": "east",
"type": "esriFieldTypeDouble",
"alias": "east"
},
{
"name": "north",
"type": "esriFieldTypeDouble",
"alias": "north"
},
{
"name": "south",
"type": "esriFieldTypeDouble",
"alias": "south"
},
{
"name": "scale",
"type": "esriFieldTypeInteger",
"alias": "scale"
},
{
"name": "title",
"type": "esriFieldTypeString",
"alias": "title",
"length": 55
},
{
"name": "edition",
"type": "esriFieldTypeString",
"alias": "edition",
"length": 85
},
{
"name": "available",
"type": "esriFieldTypeSmallInteger",
"alias": "available"
},
{
"name": "physHold",
"type": "esriFieldTypeString",
"alias": "physHold",
"length": 3
},
{
"name": "primeMer",
"type": "esriFieldTypeSmallInteger",
"alias": "primeMer"
},
{
"name": "projection",
"type": "esriFieldTypeString",
"alias": "projection",
"length": 19
},
{
"name": "publisher",
"type": "esriFieldTypeString",
"alias": "publisher",
"length": 33
},
{
"name": "datePub",
"type": "esriFieldTypeSmallInteger",
"alias": "datePub"
},
{
"name": "color",
"type": "esriFieldTypeSmallInteger",
"alias": "color"
},
{
"name": "recId",
"type": "esriFieldTypeString",
"alias": "recId",
"length": 30
},
{
"name": "note",
"type": "esriFieldTypeString",
"alias": "note",
"length": 254
},
{
"name": "location",
"type": "esriFieldTypeString",
"alias": "location",
"length": 254
},
{
"name": "bathLines",
"type": "esriFieldTypeString",
"alias": "bathLines",
"length": 5
},
{
"name": "bathInterv",
"type": "esriFieldTypeString",
"alias": "bathInterv",
"length": 50
},
{
"name": "instCallNo",
"type": "esriFieldTypeString",
"alias": "instCallNo",
"length": 50
},
{
"name": "setTitle",
"type": "esriFieldTypeString",
"alias": "setTitle",
"length": 50
},
{
"name": "sheetId",
"type": "esriFieldTypeInteger",
"alias": "sheetId"
},
{
"name": "digita",
"type": "esriFieldTypeString",
"alias": "digita",
"length": 8000
},
{
"name": "titleAlt",
"type": "esriFieldTypeString",
"alias": "titleAlt",
"length": 8000
},
{
"name": "digHold",
"type": "esriFieldTypeString",
"alias": "digHold",
"length": 8000
},
{
"name": "miradorURL",
"type": "esriFieldTypeString",
"alias": "miradorURL",
"length": 8000
},
{
"name": "iiifURL",
"type": "esriFieldTypeString",
"alias": "iiifURL",
"length": 8000
},
{
"name": "Shape_Length",
"type": "esriFieldTypeDouble",
"alias": "Shape_Length"
},
{
"name": "Shape_Area",
"type": "esriFieldTypeDouble",
"alias": "Shape_Area"
}
],
"features": [
{
"attributes": {
"OBJECTID": 1,
"label": " ",
"west": -5.8263888899999996,
"east": -5.7838888900000001,
"north": 35.770000000000003,
"south": 35.814166669999999,
"scale": 5000,
"title": "Port de Tanger",
"edition": " ",
"available": 1,
"physHold": "yes",
"primeMer": 131,
"projection": " ",
"publisher": " ",
"datePub": 1908,
"color": 31,
"recId": "agsmap026454",
"note": "\\\\ $a Relief shown by form lines and hachures. Depths shown by bathymetric isolines and soundings. | \\\\ $a \"Nota, le de\u0301tail de la ville, emprunte\u0301 au plan local espangnol, a e\u0301te\u0301 rectifie\u0301 par la triangulation et le nivellement effectue\u0301s par la",
"location": " ",
"bathLines": " ",
"bathInterv": " ",
"instCallNo": " ",
"setTitle": "French Charts",
"sheetId": 21511,
"digita": "agsmap026454",
"titleAlt": "Tangier, port, 1908",
"Shape_Length": 21584.807399988174,
"Shape_Area": 28676605.202176783
},
"geometry": {
"rings": [
[
[
-648590.64440000057,
4269019.7031000033
],
[
-648590.64440000057,
4275081.0283999965
],
[
-643859.56599999964,
4275081.0283999965
],
[
-643859.56599999964,
4269019.7031000033
],
[
-648590.64440000057,
4269019.7031000033
]
]
]
}
}
]
}
js
function exportJSONToCSV(objArray) {
var arr = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;
var str =
`${Object.keys(arr[0])
.map((value) => `"${value}"`)
.join(',')}` + '\r\n';
var csvContent = arr.reduce((st, next) => {
console.log(next);
st +=
`${Object.values(next)
.map((value) => `"${value}"`)
.join(',')}` + '\r\n';
return st;
}, str);
var element = document.createElement('a');
element.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
element.target = '_blank';
element.download = 'export.csv';
element.click();
}
What about:
var json = ... // YOUR JSON
var features = json.features;
var isFirstIterationCompleted = false;
var csv = '';
features.forEach(e => {
var attributesKeys = Object.keys(e.attributes);
if (!isFirstIterationCompleted) {
csv += attributesKeys.join(';') + '\n'; // separated by semicolon
isFirstIterationCompleted = true;
}
attributesKeys.forEach(a => {
csv += e.attributes[a] + ';';
});
csv += '\n';
})
console.log(csv);

return array with all matched elements based on user input [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I need a help with a function that returns array with matched objects based on user input.
We enter value and search only inside this keys
1. title.label
2. ['im:artist'].label
ES6 solution highly appriciated :-)
Thanks in advance.
const fetchedData = [
{
"im:name": {
"label": "John Christmas songs"
},
"im:image": [
{
"label": "https://is3-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/55x55bb.png",
"attributes": {
"height": "55"
}
},
{
"label": "https://is5-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/60x60bb.png",
"attributes": {
"height": "60"
}
},
{
"label": "https://is4-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/170x170bb.png",
"attributes": {
"height": "170"
}
}
],
"im:itemCount": {
"label": "25"
},
"im:price": {
"label": "$8.99",
"attributes": {
"amount": "8.99000",
"currency": "USD"
}
},
"im:contentType": {
"im:contentType": {
"attributes": {
"term": "Album",
"label": "Album"
}
},
"attributes": {
"term": "Music",
"label": "Music"
}
},
"rights": {
"label": "This Compilation ℗ 2008 EMI Music North America / Sony BMG Music / UMG Recordings, Inc."
},
"title": {
"label": "The Essential NOW That's What I Call Christmas - Various Artists"
},
"link": {
"attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2"
}
},
"id": {
"label": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2",
"attributes": {
"im:id": "1440793555"
}
},
"im:artist": {
"label": "John Christmas"
},
"category": {
"attributes": {
"im:id": "8",
"term": "Holiday",
"scheme": "https://music.apple.com/us/genre/music-holiday/id8?uo=2",
"label": "Holiday"
}
},
"im:releaseDate": {
"label": "2008-01-01T00:00:00-07:00",
"attributes": {
"label": "January 1, 2008"
}
}
},
{
"im:name": {
"label": "The Essential NOW That's What I Call Christmas"
},
"im:image": [
{
"label": "https://is3-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/55x55bb.png",
"attributes": {
"height": "55"
}
},
{
"label": "https://is5-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/60x60bb.png",
"attributes": {
"height": "60"
}
},
{
"label": "https://is4-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/170x170bb.png",
"attributes": {
"height": "170"
}
}
],
"im:itemCount": {
"label": "25"
},
"im:price": {
"label": "$8.99",
"attributes": {
"amount": "8.99000",
"currency": "USD"
}
},
"im:contentType": {
"im:contentType": {
"attributes": {
"term": "Album",
"label": "Album"
}
},
"attributes": {
"term": "Music",
"label": "Music"
}
},
"rights": {
"label": "This Compilation ℗ 2008 EMI Music North America / Sony BMG Music / UMG Recordings, Inc."
},
"title": {
"label": "The Essential NOW That's What I Call Christmas - Various Artists"
},
"link": {
"attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2"
}
},
"id": {
"label": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2",
"attributes": {
"im:id": "1440793555"
}
},
"im:artist": {
"label": "Various Artists"
},
"category": {
"attributes": {
"im:id": "8",
"term": "Holiday",
"scheme": "https://music.apple.com/us/genre/music-holiday/id8?uo=2",
"label": "Holiday"
}
},
"im:releaseDate": {
"label": "2008-01-01T00:00:00-07:00",
"attributes": {
"label": "January 1, 2008"
}
}
},
{
"im:name": {
"label": "Christmas"
},
"im:image": [
{
"label": "https://is2-ssl.mzstatic.com/image/thumb/Music6/v4/95/da/b2/95dab2db-b597-d466-490d-58aa56b54a17/093624942788.jpg/55x55bb.png",
"attributes": {
"height": "55"
}
},
{
"label": "https://is4-ssl.mzstatic.com/image/thumb/Music6/v4/95/da/b2/95dab2db-b597-d466-490d-58aa56b54a17/093624942788.jpg/60x60bb.png",
"attributes": {
"height": "60"
}
},
{
"label": "https://is3-ssl.mzstatic.com/image/thumb/Music6/v4/95/da/b2/95dab2db-b597-d466-490d-58aa56b54a17/093624942788.jpg/170x170bb.png",
"attributes": {
"height": "170"
}
}
],
"im:itemCount": {
"label": "16"
},
"im:price": {
"label": "$6.99",
"attributes": {
"amount": "6.99000",
"currency": "USD"
}
},
"im:contentType": {
"im:contentType": {
"attributes": {
"term": "Album",
"label": "Album"
}
},
"attributes": {
"term": "Music",
"label": "Music"
}
},
"rights": {
"label": "℗ 2011 Reprise Records"
},
"title": {
"label": "Christmas - Michael Bublé"
},
"link": {
"attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://music.apple.com/us/album/christmas/669854820?uo=2"
}
},
"id": {
"label": "https://music.apple.com/us/album/christmas/669854820?uo=2",
"attributes": {
"im:id": "669854820"
}
},
"im:artist": {
"label": "Michael Bublé",
"attributes": {
"href": "https://music.apple.com/us/artist/michael-bubl%C3%A9/799597?uo=2"
}
},
"category": {
"attributes": {
"im:id": "8",
"term": "Holiday",
"scheme": "https://music.apple.com/us/genre/music-holiday/id8?uo=2",
"label": "Holiday"
}
},
"im:releaseDate": {
"label": "2011-10-14T00:00:00-07:00",
"attributes": {
"label": "October 14, 2011"
}
}
}
]
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
var filtered = Object.filter(fetchedData, obj => obj['im:name'].label.includes('Christmas') || obj['im:artist'].label.includes('Christmas') );
console.log(filtered);
Link to fiddle
https://jsfiddle.net/pr8vxyhn/2/
I achieved goal, sorry, I promise I`ll be more precise in future and always submit my code.
you can try this approach, here I'm using the arrow function. You have to make http request and fetch your data then apply this filter function.
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);

Categories