<p><strong>Be sure to open the console to see script output.</strong></p>
<hr/>
<p>If you find this demo useful, please consider <a href="https://www.paypal.me/RobertGravelle/1" target="_blank">donating $1 dollar</a> (secure PayPal link) for a coffee or purchasing one of my songs from <a href="https://ax.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?term=rob%20gravelle" target="_blank">iTunes.com</a> or <a href="http://www.amazon.com/s/ref=ntt_srch_drd_B001ES9TTK?ie=UTF8&field-keywords=Rob%20Gravelle&index=digital-music&search-type=ss" target="_blank">Amazon.com</a> for only 0.99 cents each.</p>
<p>Rob uses and recommends <a href="http://www.mochahost.com/2425.html" target="_blank">MochaHost</a>, which provides Web Hosting for as low as $1.95 per month, as well as unlimited emails and disk space!</p>
import { Observable, timer } from "https://cdn.skypack.dev/rxjs";
import { retryWhen, tap, delayWhen, take } from "https://cdn.skypack.dev/rxjs/operators";
type UserSettings = {
settings: {
viewType: number,
isLimited?: boolean
}
};
enum ViewSelectionValues {
circle,
table
}
class UserSettingsException extends Error {
constructor(status: number, message: String) {
super(message);
// Ensure the name of this error is the same as the class name
this.name = this.constructor.name;
this.status = status;
// Set the prototype explicitly.
Object.setPrototypeOf(this, UserSettingsException.prototype);
}
}
class UserService {
constructor() {
this.userSettingsMap = new Map([
[
"1234",
{
settings: {
viewType: ViewSelectionValues.circle,
isLimited: false
}
}
],
[
"3456",
{
settings: {
viewType: ViewSelectionValues.table,
isLimited: true
}
}
]
]);
}
getSettings(userid: String) {
return new Observable(observable => {
setTimeout(() => {
if (userid === "9999") {
console.log("Throwing error.");
observable.error(
new UserSettingsException(999, "An error occured!")
);
} else if (userid === "retry") {
console.log("Throwing error for retry.");
observable.error(
new UserSettingsException(666, "An error occured!")
);
} else if (this.userSettingsMap.has(userid)) {
observable.next(this.userSettingsMap.get(userid));
} else {
console.log("User not found.");
observable.error(
new UserSettingsException(404, "User " + userid + " not found.")
);
}
}, 2000);
});
}
}
class Client {
constructor(userid) {
this.userid = userid;
this.userService = new UserService();
this.setViewType();
}
setViewType() {
let retryAttempts = 0;
this.userService.getSettings(this.userid)
.pipe(
retryWhen(errors =>
errors.pipe(
delayWhen(() => {
console.log(`Retry attempt #${++retryAttempts}`);
return timer(2000);
}),
take(3)
)
)
)
.subscribe(userSettings => {
console.log(userSettings.settings.viewType, userSettings.settings.isLimited);
this.viewType =
userSettings.settings['viewType'] || ViewSelectionValues.circle;
console.log("Got viewType: " + this.viewType);
},
error => {
console.log(error.message);
this.viewType = ViewSelectionValues.circle;
if (error.status && error.status !== 404) {
throw error;
}
});
}
}
console.log("Starting demo.");
console.log("Creating client 1234.");
let client = new Client('1234');
console.log("Creating new client with no settings yet.");
client = new Client('4444');
console.log("Creating client 3456.");
client = new Client('3456');
console.log("Creating error client.");
client = new Client('9999');
console.log("Creating retry client.");
client = new Client('retry');
View Compiled
This Pen doesn't use any external CSS resources.