RXJS combineLatest/zip questions - javascript

I want to get the console.log result: ["abc", 122, 123], and the operations zip/combineLatest generally fit for my needs.
However, when time or time2 don't have any value, for example:
var time = Rx.Observable.of();, then the console.log result isn't ["abc", 122, 123].
So how to solve it?
var time = Rx.Observable.of(['abc']);
var time2= Rx.Observable.of([122,123]);
Rx.Observable.zip(time,time2
, (a, b) => [...a, ...b])
.subscribe(data => console.log("data:",data));
Rx.Observable.merge(time,time2).subscribe(data => {
console.log("data-M:",data);
})
Rx.Observable.combineLatest(time,time2
, (a,b) => {return a.concat(b)})
.subscribe(data => console.log("data:",data));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script src="https://unpkg.com/#reactivex/rxjs#5.0.3/dist/global/Rx.js"></script>
</body>
</html>

That is because Rx.Observable.of() creates an empty observable. Both combineLatest and zip will fire when they all have a value. That is why it never fires. Rx.Observable.of('') will work though.

Related

How to get REST API JavaScript fetch object value to HTML?

How can I get printed console object value to HTML?
I have JavaScript fetch code like this:
const comments = fetch("https://api.github.com/repos/pieceofdiy/comments/issues/1")
.then((response) => response.json())
.then((labels) => {
return labels.comments;
});
const printComments = () => {
comments.then((number) => {
console.log(number);
});
};
printComments()
printComments() numeric object value shows correct in console, but how to show it in HTML
to <span id="comments">..</span> ?
With JS you can edit the DOM Hierarchy by searching for your desired Element to change.
const commentsEl = document.querySelector('.comments');
commentsEl.innerHTML = printComments();
With document.querySelector(CSS-Selector) you can search the DOM-Tree for a sufficient Element matching your Selector
We store the Element in a variable and change the Content of this Element by saving the comments in the property .innerHTML.
I've added a snippet demonstrating the changes below, and also changed some bits to improve your code.
As the fetch-Method is asynchronous, you’ll see fetching comments ... for a brief moment, as we change the content when the fetch finished and we got the results.
const commentsEl = document.querySelector('.comments');
// We fetch the comments as before
fetch("https://api.github.com/repos/pieceofdiy/comments/issues/1")
.then((response) => response.json())
.then((labels) => {
// But when we get the results, we immedietly change the contents of the comments span.
commentsEl.innerHTML = labels.comments;
});
<div class="container">
<p>Comments:</p>
<span class="comments">Fetching comments ...</span>
</div>
You could try setting a p tag with an id, ex: <p id=“comments”>and then using document.getElementById(“comments”).innerValue = number;
Place that second piece of code into printComments()
First you need to get your span tag in your html document.
Then define the innerHtml property of the span element by the value returned by the promise, in this case in your case the value is returned through a callback, so you simply have to perform the process in the scope of the callback.
Here is a snippet to illustrate this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<span id="comments"></span>
<script>
const span = document.getElementById("comments");
const comments = fetch("https://api.github.com/repos/pieceofdiy/comments/issues/1")
.then((response) => response.json())
.then((labels) => {
return labels.comments;
});
comments
.then(res => span.innerHTML = res)
.catch(err => console.log(err));
</script>
</body>
</html>
But it can be done more cleanly this way:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ol>
<li>Comments: <span id="comments1"></span></li>
<li>Comments: <span id="comments2"></span></li>
<li>Comments: <span id="comments3"></span></li>
</ol>
<script>
const comments1 = document.getElementById("comments1");
const comments2 = document.getElementById("comments2");
const comments3 = document.getElementById("comments3");
const printComment = async (url, HTMLTag) => {
try {
const request = await fetch(url);
const response = await request.json();
HTMLTag.innerHTML = response.comments;
} catch (error) {
console.log(error);
}
};
printComment("https://api.github.com/repos/pieceofdiy/comments/issues/1", comments1);
printComment("https://api.github.com/repos/pieceofdiy/comments/issues/1", comments2);
printComment("https://api.github.com/repos/pieceofdiy/comments/issues/1", comments3);
</script>
</body>
</html>
Good luck !

How to get only an specific piece of json data

This is my first time with javascript, I know Its awful hahaha
I'm looking for a way to display only the currentDateTime value from the json, the number after the T to be more specific, when clicking the button, but everytime I click on the button, It displays all the json data. Is there a better way to do this, I mean, a correct way?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>World Clock</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 class="msg">World Clock</h1>
<p class="dsc">Click one of the buttons to see the current time</p>
<button class="btn1" onclick="estFunc()">Eastern Standard Time (EST)</button>
fetch('http://worldclockapi.com/api/json/est/now')
.then(response => response.json())
.then(data => time = data)
.then(() => console.log(time["currentDateTime"]))
function estFunc() {
const obj = {time};
const estJson = JSON.stringify(obj);
document.getElementById("est").innerHTML = estJson;
}
const estFunc = async () => {
const response = await fetch('http://worldclockapi.com/api/json/est/now', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json(); //extract JSON from the http response
// do something with JSON
document.getElementById("est").innerHTML = data.currentDateTime;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>World Clock</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 class="msg">World Clock</h1>
<p class="dsc">Click one of the buttons to see the current time</p>
<button class="btn1" onclick="estFunc()">Eastern Standard Time (EST)</button>
<div id="est"></div>
</body>
</html>
The other answers are not wrong but don't provide an explanation on what's wrong.
Your problem is that you stringify the whole object you get from the server, not just the currentDateTime.
fetch('http://worldclockapi.com/api/json/est/now')
.then(response => response.json())
.then(data => time = data.currentDateTime.time) // only assign currentDateTime.time instead of everything
.then(() => console.log(time.currentDateTime.time))

Array methods inside HTML

I'm trying to make a very simple html document with some vanilla JavaScript to sort some elements in it.
I've been able to use .map() to print all the elements of an array, but I'd like to include them in html elements. For example. using an <h1> or a <p>.
This is the code I have so far:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
</head>
<body onload="mapping()">
<h1>
<script>
const array = [1, 2, 3];
function mapping() {
array.map(arrayItem => {
document.write(arrayItem)
})
}
</script>
</h1>
</body>
</html>
How can I include HTML inside the script, so I can do something with each one of those returned elements? I mean, something like this:
<script>
const array = [1, 2, 3];
function mapping() {
array.map(arrayItem => {
<h1>document.write(arrayItem)</h1>
})
}
</script>
This should work.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
</head>
<body onload="mapping()">
<script>
const array = [1, 2, 3];
function mapping() {
array.forEach(arrayItem => {
var newEle = document.createElement('h1');
newEle.innerHTML = arrayItem;
document.body.appendChild(newEle);
});
}
</script>
</body>
</html>
I guess what you want to do is something like this:
<div>
<script type="text/javascript">
document.write("<h1>Main title</h1>")
</script>
</div>
You might want to consider checking the documentation for Javascript at the link I provided. It gives a lot of useful examples and methods. I took the snippet code from there.Hope it helps.

what does "Object.assign() does not throw on null or undefined source values" mean?

I read this on mozilla
"Object.assign() does not throw on null or undefined source values"
When I try it on jsbin, it seems not work.
var obj1 = {p: null};
var obj2 = {p: "new"};
console.log(_.assign(obj1, obj2));
console.log(_.merge(obj1, obj2));
console.log(Object.assign(obj1, obj2));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
</head>
<body>
</body>
</html>
can anybody help me to explain why? tks for any reply~
It just means you can write
console.log(Object.assign({}, null));
and it will not throw an error. Nothing more. The example you provided works as expected.

why bindCallback is not a function?

Hi I am using this rxjs libraray .I am getting this error
Rx.Observable.bindCallback is not a function
here is my code
http://jsbin.com/tuxucotake/edit?html,js,console,output
I am reading doc from here
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html
var getJSONAsObservable = Rx.Observable.bindCallback(jQuery.getJSON);
var result = getJSONAsObservable('http://mysafeinfo.com/api/data?list=englishmonarchs&format=json');
result.subscribe(x => console.log(x), e => console.error(e));
You are using RXJS 4 but the docs you have linked to are RXJS 5
Based on #Günter Zöchbauer answer, bindCallback() is not anymore part of Observableso the correct usage for current version of RxJs (6) would be:
jsbin
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<title>JS Bin</title>
</head>
<body>
</body>
</html>
js
var getJSONAsObservable = rxjs.bindCallback(jQuery.getJSON);
var result = getJSONAsObservable('https://mysafeinfo.com/api/data? list=englishmonarchs&format=json');
result.subscribe(
([data,textStatus,jqXhr]) => console.log(data),
e => console.error(e));
Respectively for node:
const Rx = require('rxjs')
const {bindCallback} = Rx;
var getJSONAsObservable = bindCallback(jQuery.getJSON);
....

Categories

Resources