I have JSON file with 3 objects:
[
{
"image": "assets/image.jpg",
"title": "Text",
"text": "Some text",
"date": "23/11/2013"
},
...
]
And 3 HTML elements:
<div class="blog-post">
<img src="" class="blog-image"/>
<h2 class="blog-title"></h2>
<p class="blog-text"></p>
<div class="blog-date"></div>
</div>
I know how to fetch datas from 1 object to 1 html element:
((() => {
const getJSON = (url, callback) => {
const xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'json';
xhr.onload = () => {
const status = xhr.status;
if (status === 200) {
callback(null, xhr.response);
} else {
callback(status);
}
};
xhr.send();
};
const blogTitle = document.querySelector('.blog-title');
const blogText = document.querySelector('.blog-text');
const blogDate = document.querySelector('.blog-date');
const blogImage = document.querySelector('.blog-image');
getJSON('/test-data.json', (err, data) => {
if (err != null) {
return false;
} else {
blogImage.src = data.image;
blogTitle.innerText = data.title;
blogText.innerText = data.text;
blogDate.innerText = data.date;
}
});
}))();
But how can i make loop around all objects in json file and insert datas to html elements?
So your JSON file will return an array, and we can loop through the array like this:
getJSON('./test-data.json', (err, data) => {
if (err != null) {
return false;
} else {
data.forEach(obj => {
createElements(obj);
});
}
});
That createElements is a function I wrote:
function createElements(obj) {
const mainDiv = document.createElement('div');
mainDiv.classList.add('blog-post');
const img = document.createElement('img');
img.classList.add('blog-image');
img.src = obj['image'];
const title = document.createElement('h2');
title.classList.add('blog-title');
title.innerHTML = obj['title'];
const text = document.createElement('p');
text.classList.add('blog-text');
text.innerHTML = obj['text'];
const date = document.createElement('div');
date.classList.add('blog-date');
date.innerHTML = obj['date'];
mainDiv.appendChild(img);
mainDiv.appendChild(title);
mainDiv.appendChild(text);
mainDiv.appendChild(date);
document.querySelector('body').appendChild(mainDiv);
}
Pretty verbose, but this will add a new post to the HTML body for every object in your JSON array with the correct classes. You can change the last line of the createElements function to append it to a different element than the body.
Related
The problem is when i do no not see the form data in the console. I do not know what is wrong. here is the code:
So I got firstly the nodes and tried to create a function thta reads the file and a function that returns a src that would be stored in the readForm data function
//nodes
const mainContainer = document.getElementById("main");
const postTitleNode = document.getElementById("postTitle");
const postDateNode = document.getElementById("postDate");
const postFileNode = document.getElementById("postFile");
const postContentNode = document.getElementById("postContent");
//image file reader
function readImageFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", () => {
resolve(reader.result);
});
reader.addEventListener("error", () => {
reject(reader.error);
});
reader.readAsDataURL(file);
});
}
//reading the src of the image uploaded
function readFileSrc(elementNode) {
return new Promise((resolve, reject) => {
elementNode.addEventListener("change", async () => {
const file = elementNode.files[0];
if (file.type.startsWith("image/")) {
const dataUrl = await readImageFile(file);
postFileNode.value = dataUrl;
resolve(dataUrl);
} else {
console.error("Selected file is not an image.");
reject("Selected file is not an image.");
}
});
});
}
//clear form data
function clearInputValue() {
postTitleNode.value = "";
postDateNode.value = "";
postFileNode.value = "";
postContentNode.value = "";
}
//get form Data
async function readFormData() {
//values: store the values in an object
const postFile = await readFileSrc(postFileNode);
const formData = {
title: postTitleNode.value,
postDate: postDateNode.value,
postFile: postFile,
postContent: postContentNode.value,
};
console.log(formData);
return formData;
}
//onClick function
async function onClickEvent() {
//read data
await readFormData();
//clear data after clicking
clearInputValue();
}
//buttons
const createPostButton = document.getElementById("modalCreatePostButton");
createPostButton.addEventListener("click", onClickEvent);
what can I do to solve the problem or where is my mistake? why am i not getting any data in the console
Just started a 'Writing JS for the Web' course with following exercise and code, but getting 'unexpected end of JSON input' message upon completion of the exercise. Any idea what's going wrong? I'm coding in the following Codepen: https://codepen.io/nicolaspatschkowski/pen/GRJBZjy?editors=1111
// Get form elements
const titleInput = document.getElementById('title');
const contentInput = document.getElementById('content');
const submitButton = document.getElementById('submit-button');
const url = 'https://us-central1-open-classrooms-js-for-the-web.cloudfunctions.net/widgets';
// Get DOM elements for showing response
const responseMessage = document.getElementById('response-message');
const responseTitle = document.getElementById('response-title');
const responseId = document.getElementById('response-id');
const responseContent = document.getElementById('response-content');
submitButton.addEventListener('click', ($event) => {
$event.preventDefault();
const post = {
title: titleInput.value,
content: contentInput.value
};
submitFormData(post);
});
function makeRequest(data) {
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest();
request.open('POST', url + '/create-post');
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status === 201) {
resolve(JSON.parse(request.response));
} else {
reject(JSON.parse(request.response));
}
}
};
request.setRequestHeader('Content-Type', 'application/json');
request.send(JSON.stringify(data));
});
}
async function submitFormData(post) {
try {
const requestPromise = makeRequest(post);
const response = await requestPromise;
responseMessage.textContent = response.message;
responseTitle.textContent = response.post.title;
responseId.textContent = response.post.id;
responseContent.textContent = response.post.content;
} catch (errorResponse) { responseMessage.textContent = errorResponse.error;
}
};
The uploader multiple files in one request so customized file uploads after getting a response using clearQueue() not working get single file only removed
core.js:3926 ERROR TypeError: Cannot read property 'abort' of
undefined
at FileUploaderCustom.push../node_modules/ng2-file-upload/file-upload/file-uploader.class.js.FileUploader.cancelItem
(file-uploader.class.js:112)
at FileItem.push../node_modules/ng2-file-upload/file-upload/file-item.class.js.FileItem.cancel
(file-item.class.js:38)
at FileUploaderCustom.push../node_modules/ng2-file-upload/file-upload/file-uploader.class.js.FileUploader.removeFromQueue
(file-uploader.class.js:85)
at FileItem.push../node_modules/ng2-file-upload/file-upload/file-item.class.js.FileItem.remove
(file-item.class.js:41)
at FileUploaderCustom.push../node_modules/ng2-file-upload/file-upload/file-uploader.class.js.FileUploader.clearQueue
(file-uploader.class.js:92)
at FileUploaderCustom.uploaderOnward.onSuccessItem (mandate-initial.component.ts:267)
at FileUploaderCustom.push../node_modules/ng2-file-upload/file-upload/file-uploader.class.js.FileUploader._onSuccessItem (file-uploader.class.js:396)
at XMLHttpRequest.xhr.onload [as __zone_symbol__ON_PROPERTYload] (fileUploader.ts:71)
at XMLHttpRequest.wrapFn (zone.js:1255)
at ZoneDelegate.invokeTask (zone.js:431)
customized file uploads .ts
export class FileUploaderCustom extends FileUploader {
constructor(
options: FileUploaderOptions
) {
super(options);
}
uploadAllFiles(): void {
// const _this = this;
const xhr = new XMLHttpRequest();
const sendable = new FormData();
const fakeItem: FileItem = null;
this.onBuildItemForm(fakeItem, sendable);
for (const item of this.queue) {
item.headers = [];
item.withCredentials = true;
item.formData = [];
item.isReady = true;
item.isUploading = true;
item.isUploaded = false;
item.isSuccess = false;
item.isCancel = false;
item.isError = false;
item.progress = 0;
item.index = void 0;
if (typeof item._file.size !== 'number') {
throw new TypeError('The file specified is no longer valid');
}
sendable.append('file', item._file, item.file.name);
}
if (this.options.additionalParameter !== undefined) {
Object.keys(this.options.additionalParameter).forEach((key) => {
sendable.append(key, this.options.additionalParameter[key]);
})
}
xhr.onerror = () => {
this.onErrorItem(fakeItem, null, xhr.status, null);
}
xhr.onabort = () => {
this.onErrorItem(fakeItem, null, xhr.status, null);
}
xhr.open('POST', this.options.url, true);
xhr.withCredentials = true;
if (this.options.headers) {
for (let _i = 0, _a = this.options.headers; _i < _a.length; _i++) {
const header = _a[_i];
xhr.setRequestHeader(header.name, header.value);
}
}
if (this.authToken) {
xhr.setRequestHeader(this.authTokenHeader, this.authToken);
}
xhr.onload = () => {
const headers = this._parseHeaders(xhr.getAllResponseHeaders());
const response = this._transformResponse(xhr.response, headers);
const gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
const method = '_on' + gist + 'Item';
for (const item of this.queue) {
this[method](item, response, xhr.status, headers);
}
this._onCompleteItem(this.queue[0], response, xhr.status, headers);
}
xhr.send(sendable);
}
}
responses
this.uploaderUpdate.onSuccessItem = (item, response, status, headers) => {
this.uploadResult = JSON.parse(response);
console.log(this.uploadResult)
if (this.uploadResult.rescode == "0000") {
this.uploaderUpdate.clearQueue();
this.editMyContainer = !this.editMyContainer;
this.toastyService.success(this.uploadResult.Description);
} else if (this.uploadResult.rescode == "0001") {
this.toastyService.error(this.uploadResult.ErrorDescription);
} else if (this.uploadResult.rescode == "0002") {
this.toastyService.error(this.uploadResult.ErrorDescription);
}
};
I have a row with value like this below:
{
"id": 1,
"token": "abcd"
}
How do I delete and save the value without "token" so it becomes this?
{
"id": 1
}
Do I need to first get the object, modify it then save back?
Maybe this will help you:
function patch(db, id, delta) {
return new Promise((resolve, reject) => {
const tx = db.transaction('mystore', 'readwrite');
tx.onerror = (event) => reject(event.target.error);
tx.oncomplete = () => resolve();
const store = tx.objectStore('mystore');
const request = store.get(id);
request.onsuccess = (event) => {
const object = event.target.result;
if (!object) {
reject(new Error(`No matching object for ${id}`));
return;
}
for (const prop in delta) {
if (typeof delta[prop] === 'undefined') {
delete object[prop];
} else {
object[prop] = delta[prop];
}
}
store.put(object);
};
});
}
async function dostuff() {
let db;
const id = 1;
const delta = {
token: undefined
};
try {
db = await connect();
await patch(db, id, delta);
} finally {
if (db) {
db.close();
}
}
}
so I have a selector that contains multiple options and below that I have a paragraph the content of which would change in accordance to the selected option in the select menu. I used find method to loop through the array and return the element(which is an object) that satisfy find function. however there is a problem with find method that I could not figure out.
'use strict';
{
function fetchJSON(url, cb) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = () => {
if (xhr.status < 400) {
cb(null, xhr.response);
} else {
cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`));
}
};
xhr.onerror = () => cb(new Error('Network request failed'));
xhr.send();
}
function createAndAppend(name, parent, options = {}) {
const elem = document.createElement(name);
parent.appendChild(elem);
Object.keys(options).forEach(key => {
const value = options[key];
if (key === 'text') {
elem.textContent = value;
} else {
elem.setAttribute(key, value);
}
});
return elem;
}
function createLI(root, sel, options = []) {
const select = document.createElement(sel);
root.appendChild(select);
select.innerHTML = options.sort().map(repo => `<option value="${repo.id}">${repo.name}</option>`).join('\n');
select.addEventListener("change", function () {
const chosenRepoId = this.value;
const selectedRepo = options.find(repo => repo.id === chosenRepoId);
document.getElementById('repoInfo').innerHTML = selectedRepo.description;
});
}
function main(url) {
fetchJSON(url, (err, data) => {
const root = document.getElementById('root');
if (err) {
createAndAppend('div', root, { text: err.message, class: 'alert-error' });
} else {
// createAndAppend('pre', root, { text: JSON.stringify(data, null, 2) });
createLI(root, 'select', data);
}
});
}
const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
window.onload = () => main(HYF_REPOS_URL);
}
````js
this.value returns string.
In the comparison - const selectedRepo = options.find(repo => repo.id === chosenRepoId);
you are using strict equality operator and your chosenRepoId is numeric. So, first convert the selected value to number (use + or parseInt).
const chosenRepoId = +this.value;
const selectedRepo = options.find(repo => repo.id === chosenRepoId);