Add a loading animation while the promise loads and displays the JSON - javascript

I finished the functionality side of this simple app but now I want to add some good UX aswell so I want to add a loading animation (a spinner) while the JSON loads and before it displays the result of the promise, but I cannot seem to find a solution by googling.
Here is the pen: https://codepen.io/kresimircoko/pen/ZLJjVM.
Here is the JavaScript code:
const API_KEY = '?api_key=625023d7336dd01a98098c0b68daab7e';
const root = 'https://www.warcraftlogs.com:443/v1/';
const zonesBtn = document.querySelector('#zones');
const responseList = document.querySelector('#response');
console.clear();
const requestJSON = objType => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
try {
resolve(JSON.parse(this.responseText));
}
catch (e) {
reject(e);
}
};
xhr.onerror = reject;
xhr.open('GET', root + objType + API_KEY);
xhr.send();
});
};
function displayBosses(zoneID) {
let bosses = document.querySelectorAll(`.bosses[data-zoneid="${zoneID}"]`);
requestJSON('zones')
.then(data => {
let output = '';
data.find(zone =>
zone.id === parseInt(zoneID, 10)
).encounters.map(encounter => {
output += `<li class="boss" data-zoneid="${zoneID}">${encounter.name}</li>`;
bosses.forEach(boss => {
boss.innerHTML = output;
});
}).join('');
});
}
function displayZones() {
let output = '';
requestJSON('zones')
.then(zones => {
return zones.map(zone => {
output += `
<ul data-zoneid="${zone.id}" class="zones">
<span>${zone.name}</span>
<ul data-zoneid="${zone.id}" class="bosses"></ul>
</ul>`;
response.innerHTML = output;
}).join('');
})
.then(responseList.style.display = 'flex');
}
zonesBtn.addEventListener('click', displayZones);
responseList.addEventListener('click', evt => {
const target = evt.target.parentElement;
const zoneID = target.dataset.zoneid;
displayBosses(zoneID);
if (target.classList.contains('clicked'))
target.classList.remove('clicked');
else
target.classList.add('clicked')
});

The spinner is a FontAwesome icon wrapped in a spinner div for which we control the display property to show up when the button is clicked but hide when the promise has resolved.
function displayZones() {
if (!this.classList.contains('open')) {
spinner.style.display = 'block';
this.classList.add('open');
}
let output = '';
requestJSON('zones')
.then(zones => {
spinner.style.display = 'none';
return zones.map(zone => {
output += `
<ul data-zoneid="${zone.id}" class="zones">
<span>${zone.name}</span>
<ul data-zoneid="${zone.id}" class="bosses"></ul>
</ul>`;
response.innerHTML = output;
}).join('');
})
.then(responseList.style.display = 'flex');
}

Related

Loop trough existing images, checking with Promise

Desired to have a JavaScript to loop trough a specific URL to find existing images using number incrementation ("https://6od.hu/data/hej_Page_%D.png", where %D is incremented).
Trying to Check if image exists without loading it and using the while loop:
The working code
function imageExists(url) {
return new Promise((resolve, reject) => {
const img = new Image(url);
img.onerror = reject;
img.onload = resolve;
const timer = setInterval(() => {
if (img.naturalWidth && img.naturalHeight) {
img.src = ''; /* stop loading */
clearInterval(timer);
resolve();
}
}, 10);
img.src = url;
});
}
function loadImg(i) {
const src_pattern = "https://6od.hu/data/hej_Page_0%D.png"
let src = src_pattern.replace("%D", i);
imageExists(src)
.then(() => console.log("Image exists."))
.catch(() => console.log("Image not exists."));
}
console.log(loadImg(5)); // true|false needed to return here
How this Promise object can return true/false for the loop?
I am just learning these Promise objects, please try to be descriptive. Thank you.
Desired loop
let i = 1;
while (loadImg(i)) {
console.log(i + ": " + loadImg(i)); // log all of the existing img than stop
i++;
}
I added missing return and changed then and catch handlers
Also, removed setInterval
Check one:
function imageExists(url) {
return new Promise((resolve, reject) => {
const img = new Image(url);
img.onerror = reject;
img.onload = resolve;
img.src = url;
});
}
function loadImg(i) {
const src_pattern = "https://6od.hu/data/hej_Page_0%D.png"
let src = src_pattern.replace("%D", i);
return imageExists(src)
.then(() => true)
.catch(() => false);
}
(async() => {
console.log(await loadImg(5));
})()
Loop:
function imageExists(url) {
return new Promise((resolve, reject) => {
const img = new Image(url);
img.onerror = reject;
img.onload = resolve;
img.src = url;
});
}
function loadImg(i) {
const src_pattern = "https://6od.hu/data/hej_Page_0%D.png"
let src = src_pattern.replace("%D", i);
return imageExists(src)
.then(() => true)
.catch(() => false);
}
(async() => {
for (let i = 1; true; i += 1) {
const exists = await loadImg(i)
if (!exists) break
console.log(i, exists);
}
})()

Getting a SharePoint list and attachments at the same time using javascript

Brief synopsis of what i am trying to do:
I have a list with the following fields: document type, title of the entry, and an attachments field.
I need to get the entries along with the url(s) to the attachment(s) for the list item. I have it mostly figured out, but i can't seen to get the process to wait until i have all the information before sending it to the browser page. I know how to get the things separately, but do not know how to - or if it's even possible - to get the list item and attachment info at the same time - rather than doing two separate async queries.
I would like to get the list items, group them by document type and display separate groupings on the page that open an attachment modal when you click the item's displayed title. When i try to do this, it always paints the items before the attachments are actually added to the JSON object data.
here is the code i have
var fileList = [];
var finished = false;
function loadBootstrap() {
//check for the required boostrap stuff
var bootJs = document.querySelector('head').querySelector('#bootstrap-js');
if (!bootJs) {
bootJs = document.createElement('script');
bootJs.setAttribute("src", "https://cdn.jsdelivr.net/npm/bootstrap#4.6.1/dist/js/bootstrap.bundle.min.js");
bootJs.id = "bootstrap-js";
document.querySelector('head').append(bootJs);
}
var popper = document.querySelector('head').querySelector('#popper');
if (!popper) {
popper = document.createElement('script');
popper.setAttribute("src", "https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js");
popper.id = "popper";
document.querySelector('head').append(popper);
}
}
function getList() {
try {
if (typeof $().jquery === 'unefined') {
let jqueryJs = document.createElement('script');
jqueryJs.setAttribute("src", "/netcom/sites/516SB/SiteAssets/JScripts/jquery-3.3.1.min.js");
jqueryJs.id = "jquery-js";
document.querySelector('head').append(jqueryJs);
let jqueryWaiter = setInterval(() => {
if (typeof $().jquery !== 'unefined') {
clearInterval(jqueryWaiter);
jqueryWaiter = null;
loadBootstrap();
}
});
} else {
loadBootstrap()
}
} catch {
let jqueryJs = document.createElement('script');
jqueryJs.setAttribute("src", "/netcom/sites/516SB/SiteAssets/JScripts/jquery-3.3.1.min.js");
jqueryJs.id = "jquery-js";
document.querySelector('head').append(jqueryJs);
let jqueryWaiter = setInterval(() => {
if (typeof $ !== "undefined" && typeof $().jquery !== 'unefined') {
clearInterval(jqueryWaiter);
jqueryWaiter = null;
loadBootstrap();
}
});
}
getListItems('Staff Docs List',
function (listItems) {
for (var i = 0; i < listItems.length; i++) {
GetAttachments(listItems[i],
function (sendera, args) {
console.log(args.get_message());
});
fileList.push(listItems[i]);
}
let finishedWaiter = setInterval(() => {
let totalFilesWithAttachments = fileList.map(x => x.hasAttachments).length;
let totalAttachmentsFinished = fileList.map(x => x.attachements!==undefined).length;
if (totalAttachmentsFinished == totalFilesWithAttachments) {
clearInterval(finishedWaiter);
finished = true;
buildIt();
}
});
},
function (sendera, args) {
console.log(args.get_message());
});
}
class AttachmentWindow {
constructor(attachementList, itemName) {
this.html = this.build();
}
build() {
let html = document.createElement('div');
html.className = "modal fade";
html.id = "myModal";
html.innerHTML = `<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"> Documents for <span class="item-name"></span>
<button class="close btn bnt-danger" aria-label="close modal" data-dismiss="modal">✕</button>
</div>
<div class="modal-body">
</div>
</div>`
return html;
}
}
class StaffDocs {
constructor(item) {
this.title = item.title;
this.attachments = item.attachments;
return this.build();
}
build() {
let html = document.createElement('div');
html.className = "document-item";
html.innerText = this.title;
html.title = "click to see attachments";
html.dataset.toggle = "modal";
html.dataset.target = "#myModal";
html.addEventListener('click', () => {
let modal = document.querySelector('.modal');
let title = modal.querySelector('.item-name');
title.innerText = this.title;
let content = modal.querySelector('.modal-body');
content.innerHTML = '';
this.attachements.forEach(item => {
let attachmentDiv = document.createElement('div');
attachmentDiv.innerHTML = `<div>${item.name}</div>`;
content.append(attachmentDiv);
});
});
return html;
}
}
class DocCategory {
constructor(typeName, files) {
this.typeName = typeName;
this.items = files;
this.css();
return this.build();
}
build() {
let div = document.createElement('div');
div.className = this.typeName.replace(' ', '');
div.className += " flex flex-box";
div.innerHTML = `<h2>${this.typeName}</h2><hr />`;
let fileContents = document.createElement('div');
div.append(fileContents);
fileContents.className = "fileList";
this.items.forEach(item => {
let doc = new StaffDocs(item);
fileContents.append(doc);
});
return div;
}
css() {
var style = document.querySelector('head').querySelector('#staffDocsCss');
if (!style) {
style = document.createElement('style');
document.querySelector('head').append(style)
style.id = "staffDocsCss";
style.type = "text/css";
let cssText = `.${this.typeName.replace(' ', '')}{display:flex; width:100%;flex-overflow:wrap;margin-bottom:50px;}
.${this.typeName.replace(' ', '')} .document-item{flex - basis:row;width:100%}`;
style.append(document.createTextNode(cssText));
}
}
}
function buildIt() {
var waiter = setInterval(() => {
if (finished) {
clearInterval(waiter);
let modal = new AttachmentWindow().html;
document.querySelector('body').append(modal);
let docTypes = fileList.map(x => x.documentCategory);
let target = document.querySelector('.staff-doc-area');
target.innerHTML = '';
docTypes.forEach(doc => {
let files = fileList.filter(x => x.documentCategory == doc);
let category = new DocCategory(doc, files);
target.append(category);
});
}
}, 10)
}
function getListItems(listTitle, success, error) {
let ctx = SP.ClientContext.get_current();
let list = ctx.get_web().get_lists().getByTitle(listTitle);
let qry = new SP.CamlQuery();
let listItems = list.getItems(qry);
ctx.load(listItems);
ctx.executeQueryAsync(
function () {
let listItemEnumerator = listItems.getEnumerator();
let attachmentsList = [];
while (listItemEnumerator.moveNext()) {
let item = listItemEnumerator.get_current();
Item = item;
let title = item.get_item('Title');
let documentCategory = item.get_item('Document_x0020_Type');
let hasAttachments = item.get_fieldValues()['Attachments'];
attachmentsList.push({
title: title,
documentCategory: documentCategory,
hasAttachments: hasAttachments,
fileDirRef: item.get_fieldValues()['FileDirRef'],
Id: item.get_fieldValues()['ID'],
shown: item.get_fieldValues()["Shown_x0020_on_x0020_List"]
});
}
success(attachmentsList);
},
error);
}
function GetAttachments(listItem, error) {
if (listItem.hasAttachments) {
let ctx = SP.ClientContext.get_current();
let attachmentFolderUrl = String.format('{0}/Attachments/{1}', listItem.fileDirRef, listItem.Id);
let folder = ctx.get_web().getFolderByServerRelativeUrl(attachmentFolderUrl);
let files = folder.get_files();
ctx.load(files);
ctx.executeQueryAsync(
function () {
let attachments = [];
for (let i = 0; file = files.get_item(i); i++) {
attachments.push({ url: file.get_serverRelativeUrl(), name: file.get_name() });
}
listItem["attachments"] = attachments;
},
error);
}
}
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', getList);

Passing a function to a button within dangerouslySetInnerHTML doesn't work

I am trying to add a button tag between a text when a pattern is found in react, this is done inside the dangerouslySetInnerHTML attribute. The onClick only works with alert() and console.log(), it doesn't work when I passed a function to it. What am I missing?
export const detectHashTagPattern = (text) => {
if(!text) return '';
let pattern = /This is a follow-up to your previous request #[0-9]+/gi;
let hashTagPattern = /#[0-9]+/;
text = text.replace(pattern, (res) => {
return res.replace(hashTagPattern, `<button onClick={}>${hashTagPattern.exec(res)}</button>`);
});
return text;
};
Well you could change the algorithm like the following:
function clickHandler() {
console.log("do something");
}
window.clickHandler = clickHandler;
export const detectHashTagPattern = (text) => {
if (!text) return "";
let pattern = /This is a follow-up to your previous request #[0-9]+/gi;
let hashTagPattern = /#[0-9]+/;
text = text.replace(pattern, (res) => {
return res.replace(
hashTagPattern,
// use window.<fct>()
`<button onClick="window.${window.clickHandler.name}()">${hashTagPattern.exec(
res
)}</button>`
);
});
return text;
};
You shouldn't go with this approach, as it might have other issues with the rendering in your application (depends what you're doing in the handler).
A better approach would be like this:
const splitSubject = (text) => {
if (!text) {
return [""];
}
let pattern = /This is a follow-up to your previous request #[0-9]+/gi;
if (!pattern.test(text)) {
return [text];
}
let hashTagPattern = /#[0-9]+/;
let result = text.search(hashTagPattern);
return [text.slice(0, result), text.slice(result), text.slice(result + 1)];
};
const Subject = ({ subject, handler }) => {
const splitted = splitSubject(subject);
let content = null;
if (splitted.length === 1) {
content = <span>{splitted[0]}</span>;
} else {
let [info, cmd, reqReference] = splitted;
content = (
<>
<span>{info}</span>
<button onClick={() => handler?.(reqReference)}>{cmd}</button>
</>
);
}
return <p>{content}</p>;
};
export default function App() {
const requestHandler = (num) => {
console.log(`click on '${num}'`);
};
return (
<div>
<Subject
handler={requestHandler}
subject="This is a follow-up to your previous request #9"
/>
<Subject handler={requestHandler} subject="Not matching subject" />
</div>
);
}

voxeet/dolby.io generating multiple conferences

I am using dolby.io
Till now I have implemented join conference, leave conference, start and stop video, start and stop recording, start and stop screen sharing. What I am facing issue is about multiple conference. I want to implement multiple conferences with unique conference IDs so that every user specified for relevant conference should join its own. I am not getting any idea from its official documentation.
here is my code
const initUI = () => {
const nameMessage = document.getElementById('name-message');
const joinButton = document.getElementById('join-btn');
const conferenceAliasInput = document.getElementById('alias-input');
const leaveButton = document.getElementById('leave-btn');
const startVideoBtn = document.getElementById('start-video-btn');
const stopVideoBtn = document.getElementById('stop-video-btn');
const startScreenShareBtn = document.getElementById('start-screenshare-btn');
const stopScreenShareBtn = document.getElementById('stop-screenshare-btn');
const startRecordingBtn = document.getElementById('start-recording-btn');
const stopRecordingBtn = document.getElementById('stop-recording-btn');
//const mute_unmute = document.getElementById('mute');
//oxeetSDK.conference.mute(VoxeetSDK.session.participant, VoxeetSDK.session.participant.isMuted);
//let isMuted = VoxeetSDK.conference.toggleMute(VoxeetSDK.session.participant);
nameMessage.innerHTML = `${randomName}`;
joinButton.disabled = false;
joinButton.onclick = () => {
let conferenceAlias = conferenceAliasInput.value;
/*
1. Create a conference room with an alias
2. Join the conference with its id
*/
VoxeetSDK.conference.create({ alias: conferenceAlias })
.then((conference) => VoxeetSDK.conference.join(conference, {}))
.then(() => {
joinButton.disabled = true;
leaveButton.disabled = false;
startVideoBtn.disabled = false;
startScreenShareBtn.disabled = false;
startRecordingBtn.disabled = false;
})
.catch((e) => console.log('Something wrong happened : ' + e))
};
leaveButton.onclick = () => {
VoxeetSDK.conference.leave()
.then(() => {
joinButton.disabled = false;
leaveButton.disabled = true;
startScreenShareBtn.disabled = true;
stopScreenShareBtn.disabled = true;
})
.catch((err) => {
console.log(err);
});
};
startVideoBtn.onclick = () => {
VoxeetSDK.conference.startVideo(VoxeetSDK.session.participant)
.then(() => {
startVideoBtn.disabled = true;
stopVideoBtn.disabled = false;
});
};
stopVideoBtn.onclick = () => {
VoxeetSDK.conference.stopVideo(VoxeetSDK.session.participant)
.then(() => {
stopVideoBtn.disabled = true;
startVideoBtn.disabled = false;
});
};
startScreenShareBtn.onclick = () => {
VoxeetSDK.conference.startScreenShare()
.then(() => {
startScreenShareBtn.disabled = true;
stopScreenShareBtn.disabled = false;
})
.catch((e) => console.log(e))
};
stopScreenShareBtn.onclick = () => {
VoxeetSDK.conference.stopScreenShare()
.then(() => {
startScreenShareBtn.disabled = false;
stopScreenShareBtn.disabled = true;
})
.catch((e) => console.log(e))
};
startRecordingBtn.onclick = () => {
let recordStatus = document.getElementById('record-status');
VoxeetSDK.recording.start()
.then(() => {
recordStatus.innerText = 'Recording...';
startRecordingBtn.disabled = true;
stopRecordingBtn.disabled = false;
})
.catch((err) => {
console.log(err);
})
};
stopRecordingBtn.onclick = () => {
let recordStatus = document.getElementById('record-status');
VoxeetSDK.recording.stop()
.then(() => {
recordStatus.innerText = '';
startRecordingBtn.disabled = false;
stopRecordingBtn.disabled = true;
})
.catch((err) => {
console.log(err);
})
};
};
const addVideoNode = (participant, stream) => {
const videoContainer = document.getElementById('video-container');
let videoNode = document.getElementById('video-' + participant.id);
if(!videoNode) {
videoNode = document.createElement('video');
videoNode.setAttribute('id', 'video-' + participant.id);
videoNode.setAttribute('controls', true);
//VoxeetSDK.conference.mute(VoxeetSDK.session.participant, VoxeetSDK.session.participant.isMuted);
//let isMuted = VoxeetSDK.conference.toggleMute(VoxeetSDK.session.participant);
//console.log(isMuted);
//videoNode.setAttribute('height', 240);
//videoNode.setAttribute('width', 720);
videoContainer.appendChild(videoNode);
videoNode.autoplay = 'autoplay';
videoNode.muted = true;
}
navigator.attachMediaStream(videoNode, stream);
};
const removeVideoNode = (participant) => {
let videoNode = document.getElementById('video-' + participant.id);
if (videoNode) {
videoNode.parentNode.removeChild(videoNode);
}
};
const addParticipantNode = (participant) => {
//const members_count++;
const participantsList = document.getElementById('participants-list');
// if the participant is the current session user, don't add himself to the list
if (participant.id === VoxeetSDK.session.participant.id) return;
// let participantNode = document.createElement('li');
// participantNode.setAttribute('id', 'participant-' + participant.id);
// participantNode.innerText = `${participant.info.name}`;
//alert(VoxeetSDK.session.participant);
//document.getElementById('members_count').innerText=participant.id;
let participantNode = document.createElement('div');
participantNode.setAttribute('class', 'tabcnt-item');
participantNode.setAttribute('id', 'participant-' + participant.id);
//document.getElementById('members_count').innerText = document.getElementById('members_count').innerText + 1;
//document.getElementById('members_count').innerText = members_count;
participantNode.innerText = `${participant.info.name}`;
const send_html = "<div class='tabcnt-item'><div class='row align-items-center'><div class='col-md-8'><div class='media'><img src='images/pp.png' alt=''><div class='media-body'><h3>'"+`${participant.info.name}`+"'</h3><p>email#dname.com</p></div></div></div><div class='col-md-4'><ul><li><a href='#'><i class='fas fa-video'></i></a></li><li><a href='#'><i class='fas fa-microphone'></i></a></li></ul></div></div></div>";
participantNode.innerHTML = send_html;
participantsList.appendChild(participantNode);
document.getElementById('members_count').innerText= $('.tab-cnt').length;
};
const removeParticipantNode = (participant) => {
let participantNode = document.getElementById('participant-' + participant.id);
if (participantNode) {
participantNode.parentNode.removeChild(participantNode);
document.getElementById('members_count').innerText= $('.tab-cnt').length;
}
};
const addScreenShareNode = (stream) => {
const screenShareContainer = document.getElementById('screenshare-container');
let screenShareNode = document.getElementById('screenshare');
if (screenShareNode) return alert('There is already a participant sharing his screen !');
screenShareNode = document.createElement('video');
screenShareNode.setAttribute('id', 'screenshare');
screenShareNode.autoplay = 'autoplay';
navigator.attachMediaStream(screenShareNode, stream);
screenShareContainer.appendChild(screenShareNode);
}
const removeScreenShareNode = () => {
let screenShareNode = document.getElementById('screenshare');
if (screenShareNode) {
screenShareNode.parentNode.removeChild(screenShareNode);
}
}
I am exhausted and tired of googling. It will be a great help if some can guide or provide direction towards more elaborative documentation. I have read each and every bit of dolby docs. Thanks for reading
When you call create() a new conference id is generated which is a guid specific for your account. You can call get_id() to find it. You can also specify an alias to help for readability when there may be multiple conferences active at any given time.
If you want to have multiple conferences, you should call create() multiple times. That is, the expectation is the typical app initializes only a single conference but there are multiple running instances each having its own conference and/or to invite others to an existing conference. For webapps, that may be a separate user session rather than a separate deployed mobile application. You may want to do some book keeping for what ids are generated for each user in your own services.
You may be looking for all of the conferences that are active on an account at any given time while testing or monitoring your deployed apps. You can use the Monitor API getConferences to get that list.
If you have additional questions, it is probably best to use Dolby.io Support for more personal answers and guidance.

Convert $.each and $.getJSON into vanilla javascript

I am creating a web application to collect the details from the GitHub API and display them on the screen.
I want to convert the $.getJSON and $.each into vanilla JavaScript.
I don't want to use any part of jquery in my code, hence either Ajax can be used or vanilla JavaScript.
const execute = () => {
let uname= document.getElementById('username').value;
//api for the username
let apiCall1 = `https://api.github.com/users/${uname}`;
//api for repository
let apicall2 = `https://api.github.com/users/${uname}/repos`;
$.getJSON(apiCall1, (json) => {
let fullname = json.name;
let username = json.login;
let aviurl = json.avatar_url;
let profileurl = json.html_url;
let followersnum = json.followers;
let followingnum = json.following;
let reposnum = json.public_repos;
if(fullname == undefined) {
fullname = username;
}
document.getElementById('view').style.display = 'block';
document.getElementById('result').innerHTML = `
<h1 class="text-center pt-2">USER DETAILS</h1>
<div class="row p-3">
<div class="col-md-3">
<img class="profile mt-3" src=${aviurl} alt="porfile image">
</div>
<div class="col-md-9">
<h3>FULL NAME: <span>${fullname}</span></h3>
<h3>USER NAME: <span>${username}</span></h3>
<h3>PROFILE URL: <span>${profileurl}</span></h3>
<h3>FOLLOWERS: <span>${followersnum}</span></h3>
<h3>FOLLOWING: <span>${followingnum}</span></h3>
<h3>NUMBER OF REPOSITORIES: <span>${reposnum}</span></h3>
</div>
</div>`;
let repositories, outhtml;
$.getJSON(apicall2, function(json){
repositories = json;
outputPageContent();
});
function outputPageContent() {
if(repositories.length == 0) {
outhtml = '<h1>No Repositories!</h1>';
}
else {
outhtml = `<h1>LIST OF REPOSITORIES</h1><ul>`;
$.each(repositories, function(index) {
outhtml = outhtml + `<li>${repositories[index].name}</li>`;
});
outhtml = outhtml + '</ul>';
}
document.getElementById('repo').innerHTML = outhtml;
}
})
.fail(() => {
alert("No such username exists!");
document.getElementById('username').value = "";
document.getElementById('view').style.display = 'block';
document.getElementById('result').innerHTML = "Not Available";
document.getElementById('repo').innerHTML = "Not Available";
});
};
I am unable to convert the code to vanilla JavaScript.
$.getJSON
$.getJSON('https://your.url.com', function(data) {
});
becomes:
var request = new XMLHttpRequest();
request.open('GET', 'https://your.url.com', true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
var data = JSON.parse(this.response);
} else {
// error
}
};
request.send();
or
fetch('https://your.url.com')
.then(response => response.json())
.then(data => // do something with data now)
.catch(() => // error)
$.each
$.each(collection, (item) => console.log(item));
becomes:
collection.forEach(item => console.log(item));
A great resource for migrating from jQuery to vanilla is http://youmightnotneedjquery.com/.
$.each can be replaced with forEach with arrays and Object.entries.forEach when enumerating objects. $.getJSON is likewise easily replaced with the Fetch API.
forEach
const repositoriesArray = [
"reactjs",
"angular",
"foo",
"bar"
];
repositoriesArray.forEach(repo => {
console.log(repo)
});
const repositoriesObject = {
reactjs: {
company: 'facebook'
},
angular: {
company: 'google'
}
};
Object.entries(repositoriesObject).forEach(repo => {
let key = repo[0];
let value = repo[1];
// Do something with the key/value
console.log(value.company);
});
Fetch
$.getJSON(apicall2, function(json){
repositories = json;
outputPageContent();
});
would, for example, become:
const apicall2 = 'https://jsonplaceholder.typicode.com/users';
fetch(apicall2).then(res => res.json()).then(json => {
console.log(json[0].name);
});

Categories