Display Image from RSS Feed - javascript

I'm parsing an RSS feed using rss-parser, displaying the results in a list.
The data is added to the state as such:
async getJobsData() {
let feed = await parser.parseURL(
"https://weworkremotely.com/categories/remote-design-jobs.rss"
);
this.setState({ data: feed.items });
}
The text fields are easy, as these come in as <pubDate>Mon, 20 May 2019 10:36:42 +0000</pubDate>, and are added to their respective list items using <span key={index}>{data.pubDate}</span>.
The response for images is formatted differently though. It's inserted into the generic content response, as the first item.
title: [...]
pubDate: [...]
content: "<img src="https://we-work-remotely.imgix.net/logos/0015/7503/logo.gif?ixlib=rails-2.1.3&w=50&h=50&dpr=2&fit=fill&auto=compress" alt="Logo.gif?ixlib=rails 2.1" />
How would I extract only the URL (https://we-work-remotely.imgix.net/logos/0015/7503/logo.gif?) from that field?

You can use DOMParser to parse the text representation into a DOM.
The code snippet below will print img.src.
const imgText = `<img src="https://we-work-remotely.imgix.net/logos/0015/7503/logo.gif?ixlib=rails-2.1.3&w=50&h=50&dpr=2&fit=fill&auto=compress" alt="Logo.gif?ixlib=rails 2.1" />`
const doc = new DOMParser().parseFromString(imgText, 'text/html')
console.log(doc.body.firstElementChild.src)

You can use HTML parser e.g. https://www.npmjs.com/package/fast-html-parser and get the src attribute.

Related

Restcountries API - getting names of currencies dynamically into HTML through Javascript

I am new to Javascript and I've been learning how to import a country's attributes into an HTML element. Some of you might recognize this code, it's from a tutorial, which is now outdated. I've been searching around for an updated solution, but couldn't find any.
First I have the function to fetch the data:
const getCountryData = function (country) {
fetch(`https://restcountries.com/v3.1/name/${country}`)
.then(response => response.json())
.then(data => renderCountry(data[0]));
};
Then I call that function, supplying a country getCountryData('czechia') to infuse it into an element like this:
const renderCountry = function(data, className = '') {
const html = `
<article class="country ${className}">
<img class="country__img" src="${data.flags.svg}" />
<div class="country__data">
<h3 class="country__name">${data.name.common}</h3>
<h4 class="country__region">${data.region}</h4>
<p class="country__row">${(+data.population / 1000000).toFixed(1)} people</p>
<p class="country__row">${data.fifa}</p>
</div>
</article>
`
countriesContainer.insertAdjacentHTML
('beforeend', html);
countriesContainer.style.opacity = 1;
}
This works fine, but the issue is that at the end of the HTML, where I input {data.fifa} I want to have the name of the country's main currency instead. Unfortunately, the data is structured in a way, that in order to have the currency's name displayed, I first have to call it's short name, as shown below:
"currencies": {
"CZK": {
"name": "Czech koruna",
"symbol": "Kč"
}
},
If I call the {data.currencies} into the string, I'm just gonna get an empty object back. If I call it as {currencies.CZK.name}, it works, but the issue is that if I call Sweden, for example, it won't display anything, because then it'd need to be {currencies.SEK.name}. How do I get around this? How can I can call a currency's name without having to incorporate CZK, SEK, USD, EUR etc. into the variable?
Any help is appreciated.
You can transform that object into an array:
const currencyArray = Object.values(data.currencies)
console.log(currencyArray[0].name)
If the country has many currencies, just change the index from 0 to 1, 2, ...

How to fetch Tag name using Cheerio from and XML data (JavaScript)?

I have an xml data from which I want to be able to fetch tagnames and store them or run operations based on whether a particular tag is present in data
Eg XML Data:
<MyData version="3.0">
<StudentData type="Table">
<Student type="Table">
<StudentValue type="Table">
<DateOfBirth type="Data">2009-05-31</DateOfBirth>
<StudenClass type="Data">Sixth</StudenClass>
<StudentRoll type="Data">006</StudentRoll>
<Name type="Table">
<FirstName type="Data">MMMMM</FirstName>
<LastName type="Data">XXXXXXX</LastName>
</Name>
<Performance type="Table">
<Level type="Data">Honor</Level>
</Performance>
</StudentValue>
<Contact type="Table">
<Email type="Data">xyx#xyz.com</Email>
</Contact>
</Student>
</StudentData>
I am able to however fetch the values & attr as shown in below code I have been using till now:
xml= '<MyData version="3.0"><StudentData type="Table"><Student type="Table"><StudentValue type="Table"><DateOfBirth type="Data">2009-05-31</DateOfBirth><StudenClass type="Data">Sixth</StudenClass><StudentRoll type="Data">006</StudentRoll><Name type="Table"><FirstName type="Data">MMMMM</FirstName><LastName type="Data">XXXXXXX</LastName></Name><Performance type="Table"><Level type="Data">Honor</Level></Performance></StudentValue><Contact type="Table"><Email type="Data">xyx#xyz.com</Email></Contact></Student></StudentData></MyData>';
var xmlData = cheerio.load(xml, {
ignoreWhitespace: true,
xmlMode: true
});
var studentName = xmlData('MyData StudentData Student StudentValue Name').eq(0).text();
var attr = xmlData('MyData StudentData Student StudentValue Name').eq(0).attr();
var find = xmlData('MyData StudentData Student StudentValue Name').get(0).tagname;
console.log(studentName);
console.log(attr);
console.log(find);
So How do I go about fetching and storing values like the tagname "Performance" under StudentValue Tag.
Also I would like to do some actions based on a tagname/elements presence.
Like in JSON we can code in the below manner, in case of cheerio do we have something like this:
if (MyData.StudentData.Student.StudentValue.hasOwnProperty('Performance'){
//then do some actions
console.log("Student is an Honor Student");
}
You can get a tag name in cheerio like this
$('a').first().prop('tagName')
This is how we can get the children tagnames
xmlData('MyData StudentData Student StudentValue').children().get(4).tagName;

Get list of videos youtube api

so I'm trying to create a web app that when you insert a search it gets the data from the youtube API using JSON and renders a list with the videos matching your search. When it retrieves it's getting some Letter and numerical answer but not a list of the videos. Any help in the right direction will be appreciated. This is the HTML for it:
<div class="search-box-container">
<form action="#" class="js-search-form search-box">
<label for="query"></label>
<input type="text" class="js-query search-form" placeholder="Search me">
<button type="submit" class="button">Search</button>
</form>
</div>
<h2>Results</h2>
<div class="js-search-results">
</div>
And this is the JS/Jquery for it:
const YOUTUBE_SEARCH_URL =
'https://www.googleapis.com/youtube/v3/search';
`const key = 'key'//(hidden for privacy concerns);`
function getDataFromApi(searchTerm, callback) {
const query = {
part: 'snippet',
key: key,
q: `${searchTerm} in:name`,
}
$.getJSON(YOUTUBE_SEARCH_URL, query, callback);
}
function renderResult(result) {
return `
<div>
<h2>
<a class="js-result-name" href="http//www.youtube.com/watch?v=${
result.id.videoId}" target="_blank">${result.id.videoId}</a></h2>
</div>
`;
}
function displayYoutubeSearchData(data) {
console.log(data);
const results = data.items.map((item, index) => renderResult(item));
$('.js-search-results').html(results);
}
function watchSubmit() {
$('.js-search-form').submit(event => {
event.preventDefault();
const queryTarget = $(event.currentTarget).find('.js-query');
const query = queryTarget.val();
queryTarget.val("");
getDataFromApi(query,displayYoutubeSearchData );
});
}
$(watchSubmit);
This is the answer that gets rendered
You were almost there: it is just a typo.
Look at the href attribute inside the template literal returned by the renderResult() method.
href="http//www.youtube.com/watch?v=${result.id.videoId}"
Mind the wrongly formed scheme (http// vs https://).
A little bit of a context:
The YouTube API returns a collection of search results (i.e. an array of objects, data.items in your code) that match the query parameters specified in the API request.
Each item contains an id object with a videoId property. That is the "alphanumeric answer" you refer to in your question. After mapping data.items into an array of result HTML templates, you are reading that video id with ${result.id.videoId}. Then you concatenate the YouTube watch URL with the video id.
You should check the JSON structure of the search result in the YouTube Data API docs. Besides id.videoId, it contains more useful information. For example, you could prefer to show to the users the title of the video using ${result.snippet.title} instead of the alphanumeric videoId.

How to get value of elements without using IDs in JavaScript

Lets say I had the following code:
<div class="post">
<h2 itemprop="name">
The Post Title
</h2>
<div class="details">
<span>
<em class="date">Jul 17, 2014 </em>
</span>
<span>
Category:
Staff Profile
</span>
</div>
How would I possibly get the values of "The Post Title" and "Staff Profile" using JavaScript without changing the HTML on the page at all? i.e. I couldn't use getElementbyID for example. I could use jQuery if I had to but would rather not if possible.
You can get these values using getElementsByTagName which returns an array
document.getElementsByTagName("a")[0].innerHTML // returns The Post Title
document.getElementsByTagName("a")[1].innerHTML // returns Staff Profile
If these links are the first ones you can use indexes 0 and 1, otherwise you should look for the right index
Update
Another way that may be simple is to select these links inside the div with the class post
var links = document.getElementsByClassName("post")[index].getElementsByTagName("a");
links[0].innerHTML; // returns The Post Title
links[1].innerHTML; // returns Staff Profile
This solution would be the best one if the index of the div with the class post doesn't change
For a jQuery based expression you can use this:
$('a').map(function() {
return [this.href, this.textContent];
}).get();
which should return:
[ [ 'http://www.example.com', 'The Post Title' ],
[ 'http://sitename/category/staff-profile/', 'Staff Profile' ] ]
Should you specifically want the original relative URLs instead of the normalised full URLs, use this.getAttribute(href) in place of this.href
For a pure (ES5) equivalent:
[].map.call(document.getElementsByTagName('a'), function (el) {
return [el.href, el.textContent];
});
Older browsers that don't support the W3C standard .textContent property may require the .innerText property instead, e.g.:
return [el.href, el.textContent || el.innerText];
You can do:
var posts = document.querySelector('.post');
for (var i = 0; i < posts.length; i++) {
var links = document.querySelectorAll('a');
var title = links[0].innerText || links[0].textContent;
var profile = links[1].innerText || links[1].textContent;
}
If you are using a more modern browser, you can use document.querySelectorAll() which takes in CSS style selector syntax.
var aList = document.querySelectorAll('.post a');
for (var i = 0; i < aList.length; ++i) {
alert(aList[i].innerHTML);
}
JSFiddle
I used '.post a' rather than just 'a' because I assume your page may have other 'a' tags in it that you don't necessarily want.

Dojo: dijit.form.filteringselect dynamically add options from Json

I am getting data from json file, now i want to add it to filteringselect. i tried below code but its not adding, please help me
HTML code==
<select data-dojo-type="dijit/form/FilteringSelect"
id="education"></select>
Javascrip code==
request.get("/json/education.json", {
handleAs: "json"
}).then(function(data) {
var node = dijit.byId('education');
dojo.forEach(data.items, function(desc, index){
node.addOption({
label: desc.name,
value: desc.value
});
});
},
function(error){});
Json code
{
"title":"Education",
"items":[
{"name":"Select Education","value":"0"},
{"name":"B.A", "value":"1"},
{"name":"B.Sc" ,"value":"2"},
...........................
The store of FilteringSelect can be set dynamically, based on the ajax call.
var str = new dojo.store.Memory(optionData);
dijit.byId('widgetId').set('store',str);
But, your json data must be like this:-
var optionData={
data:[
{id:'aaaaaa',name:'aaaaaa'},
{id:'bbbbbb',name:'bbbbbb'}
]
};
The above example will actually replace the store. If, the new data from ajax call need to be appended to the existing options, then
//str is the existing store of FilteringSelect field above
dojo.forEach(result.data, function(optionSet, index){
str.add(optionSet);
});
Note to remember: 'addOption' is available only for Select. Not for FilteringSelect.
I hope this helps:
dijit.byId("select_id").store.root.add(dojo.create("option",{ value: "some", innerHTML: "label of option"}));
To remove the existing elements did just that:
var size = dijit.byId("select_id").store.root.removeChild.length;
for(var i=size; i>=0; i--){ dijit.byId("select_id").store.root.removeChild(dijit.byId("select_id").store.root.children[size-1]);
}

Categories

Resources