JavaScript beginner: why does this not work? - javascript

My html page is not responding to this code I wrote in JS, i'm a total beginner, and just started learning JS, can somebody tell me why this doesn't work?
/* this is a practice file that'll play with js
nothing strange to look at here folks! */
var firstName = 'Steven';
var lastName = 'Curry';
var fullName = firstName + ' ' + lastName;
function Hotel(HotelName){
this.HotelName = HotelName;
this.numRooms = 20;
this.numGuests;
this.checkAvailability {
if(numRooms != 20 ){
return true;
}
else{
return false;
}
}
this.getHotelName = function(){
//can it work with this dot operator?
return this.HotelName;
}
}
var HiltonHotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = getHotelName();
var el = document.getElementById('name');
el.textContent = fullName;
<!DOCTYPE html>
<html>
<body>
<div id = 'greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id = 'hotelName'>Hyatt</span>
</div>
<script
src = "https://stacksnippets.net/js">
</script>
</body>
</html
I'm pretty sure it's ordering and my syntax i need to work on, any advice is greatly appreciated thank you!

Few misunderstandings:
checkAvailability is a function, you are missing parens.
while accessing the getHotelName function, you have to refer to the HiltonHotel variable, to be able to access and call that function.
few minor errors in your html code, while operating in code snippet, you don't have to add a separate script, it's connected together by default.
var firstName = 'Steven';
var lastName = 'Curry';
var fullName = firstName + ' ' + lastName;
function Hotel(HotelName) {
this.HotelName = HotelName;
this.numRooms = 20;
this.numGuests;
this.checkAvailability = function() { // it's a function (missing parens)
if (numRooms != 20) {
return true;
} else {
return false;
}
}
this.getHotelName = function() {
return this.HotelName;
}
}
var WeiHotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = WeiHotel.getHotelName(); // refer to the `WeiHotel` variable
var el = document.getElementById('name');
el.textContent = fullName;
<div id='greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id='hotelName'>Hyatt</span></h1>
</div>

An extension to the answer of #KindUser:
You're not using closures anywhere in this class to store some private state. Therefore you should attach the methods to the prototype and not to the instance itself. It's more economic, because now all instances share one function, not one per instance. And the JS engine can optimize that better.
Then, you have another error in checkAvailability: numRooms needs to be addressed as this.numRooms because it is a property of this instance, and there is no variable with this name.
And one about style. If you have something like
if(condition){
return true;
}else{
return false;
}
you can simplify this to:
return condition;
//or if you want to enforce a Boolean value,
//but your condition may return only a truthy/falsy value:
return Boolean(condition);
//sometimes also written as:
return !!(condition);
Next. Stick to the coding standards. In JS a variable/property starting with an uppercase letter would indicate a class/constructor, therefore HotelName, HiltonHotel, WeiHotel are misleading.
And I find the property name hotelName redundant and counter-intuitive. Imo you have a Hotel, it has a name, but that's just an opinion.
var firstName = 'Steven';
var lastName = 'Curry';
var fullName = firstName + ' ' + lastName;
function Hotel(name) {
this.name = name;
this.numRooms = 20;
this.numGuests;
}
Hotel.prototype.checkAvailability = function() {
return this.numRooms !== 20;
}
Hotel.prototype.getHotelName = function() {
return this.name;
}
var hotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = hotel.getHotelName(); // refer to the `weiHotel` variable
var el = document.getElementById('name');
el.textContent = fullName;
<div id='greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id='hotelName'>Hyatt</span></h1>
</div>
or as an ES6 class (and some playin around):
class Person{
constructor(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
//this is a getter, you can read it like a property
get fullName(){
return this.firstName + " " + this.lastName;
}
//this function is implicitely called whenever you try to convert
//an instance of `Person` into a string.
toString(){
return this.fullName;
}
}
class Hotel{
constructor(name) {
this.name = name;
this.numRooms = 20;
this.numGuests;
}
checkAvailability() {
return this.numRooms !== 20;
}
getHotelName() {
return this.name;
}
}
var steve = new Person('Steven', 'Curry');
var hotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = hotel.getHotelName(); // refer to the `weiHotel` variable
var el = document.getElementById('name');
el.textContent = steve.fullName;
//this uses the `toString()` method to convert the `Person` steve into a string
//for people, this makes sense, for the Hotel you'd want to think:
// - where do I want to use this?
// - and what should this string contain?
console.log("Hello, I'm " + steve + " and I'm at the "+ hotel.name);
<div id='greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id='hotelName'>Hyatt</span></h1>
</div>

Related

Making an output of frends names instead of IDs

Can somebody help me with this, i m new to javaScript and i m stuck at this point.I made an output of certain object within my array ,that output is writing a persons values, within that object(Osoba) there is an array of his friends and all values inside are IDs of each person, http://prntscr.com/i9m2ti how can i make that ID of a friend array ( within the object ) to be a first name and surname of that person which id is in array and when i want to output a certain object so there will be friends[ their names instead of IDs], can someone write me down how can i do that. Thanks for understanding.
class Osoba{
constructor(id,firstName,surname,age,gender,friends){
this._id = id ;
this._firstName = firstName;
this._surname = surname;
this._age = age;
this._gender = gender;
this._friends = friends;
}
get id() {
return this._id;
}
set id(id){
this._id = id;
}
get firstName() {
return this._firstName;
}
set firstName(firstName){
this._firstName = firstName;
}
get surname() {
return this._surname;
}
set surname(surname){
this._surname = surname;
}
get age() {
return this._age;
}
set age(age){
this._age = age;
}
get gender() {
return this._gender;
}
set gender(gender){
this._gender = gender;
}
get friends() {
return this._friends;
}
set friends(friends){
this._friends = friends;
}
}
var osobe = []; // my array
$(function() {
$.getJSON('https://raw.githubusercontent.com/Steffzz/damnz/master/
data.json' , function(data)
{
var json = jQuery.parseJSON(JSON.stringify(data));
for(person of json)
{
var id = person['id'] ;
var firstName = person['firstName'] ;
var surname = person['surname'] ;
var age = person['age'] ;
var gender= person['gender'] ;
var friends = person['friends'] ;
var x = new Osoba(id,firstName,surname,age,gender,friends);
osobe.push(x); //filling array with objects and their values
}
console.log(osobe);
document.write(JSON.stringify(osobe[0])) //output of a certain object
})
});
Assuming json is an array and contains all people you can map over friends array and find the person with that id: person['friends'].map( and json.find(function(person){person.id===friendId});.
Then return an object containing that person's first and last name:
console.log("json is:",JSON.stringify(json,undefined,3));
var friends = person['friends'].map(
function(friendId){
console.log("friendID is:",friendId);
var friend = json.find(function(person){return person.id===friendId;});
console.log("friend is:",JSON.stringify(friend,undefined,2));
return {
firstName:friend.firstName,
surname:friend.surname
}
}
);
Now if that "does not work" could you please specify the output of the logs, any errors and expected results versus actual results?
UPDATE FULL CODE
Since the json is all your data you can pass that into your Osoba constructor. The friends getter will use the data to create an array Osaba items that will have data and friends that will create an array of Osaba ...
class Osoba {
constructor(id, firstName, surname, age, gender, friends, data) {//added data
this._id = id;
this._firstName = firstName;
this._surname = surname;
this._age = age;
this._gender = gender;
this._friends = friends;
this._data = data;//data has all the people
}
get id() {
return this._id;
}
set id(id) {
this._id = id;
}
get firstName() {
return this._firstName;
}
set firstName(firstName) {
this._firstName = firstName;
}
get surname() {
return this._surname;
}
set surname(surname) {
this._surname = surname;
}
get age() {
return this._age;
}
set age(age) {
this._age = age;
}
get gender() {
return this._gender;
}
set gender(gender) {
this._gender = gender;
}
//modified friends getter returning an array of Osoba items
get friends() {
var me = this;
return this._friends.map(
function (friendId) {
var friend = me._data.find(function (person) { return person.id === friendId; });
return new Osoba(
friend.id,
friend.firstName,
friend.surname,
friend.age,
friend.gender,
friend.friends,
me._data
);
}
);
}
set friends(friends) {
this._friends = friends;
}
}
$.getJSON('https://raw.githubusercontent.com/Steffzz/damnz/master/data.json')
.then(
json => {
var people = json.map(
person =>
new Osoba(
person.id,
person.firstName,
person.surname,
person.age,
person.gender,
person.friends,
json
)
);
//you can keep getting friends now, because Osoba is
// creating new Osoba objects based on id's and data you pass in
console.log(people[0].friends[0].friends[0].friends[0]);
}
);
instead of
var friends = person['friends'] ;
try
var friends = [];
var friendIDs = person['friends'] ; //retrieve friendIDs
for(friendID of friendIDs) { //loop over friendIDs
var friend = json[friendID]; //get friend dataset out of the json
friends.push(friend['firstName']); // add friend dataset to friends array
}
I assume here that those friends are in that json aswell. and that the ids represent that index inside that array. if the indexes aren't those ids this won't work. feel free to comment if thats the case and i'll edit my answer.
If i understand correctly you just want to use id for id, firstname, and lastname. so just pass id 3 times instead of firstname and lastname:
var x = new Osoba(id,id,id,age,gender,friends);
~~~~
Ok so what you want is actually that the id property within each friend object be the first and last name of the friend instead of an idea code. So it's basically just the opposite of what i suggested earlier. All you have to do is manipulate what you push to id. There's no obligation on it being the id from the json.
so in your case:
for(person of json){
var id = person['firstName'] + "" + person['surname']; // line to change.
var firstName = person['firstName'] ;
var surname = person['surname'] ;
var age = person['age'] ;
var gender= person['gender'] ;
var friends = person['friends'] ;
var x = new Osoba(id,firstName,surname,age,gender,friends);
osobe.push(x); //filling array with objects and their values
}

Javascript creating methods - how to output

I am looking for some guidance on the simplest way to create an output for the following code below. Just simple user output into an HTML document. Any guidance would be helpful. Also any guidance on how to use the join method so I could link two properties such as Lname and accNo also?
The idea would be to have user input box (for deposit/withdraw) and then using a button/buttons to complete the function and display the results.
<script>
function Account(fname, lname, accNo, amount) {
this.fname = fname;
this.lname = lname;
this.accNo = accNo;
this.balance = amount;
this.bankDeposit = deposit;
this.bankWithdraw = withdraw;
}
function deposit(amount) {
this.balance += amount;
}
function withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
}
if (amount > this.balance) {
alert("Declined");
}
}
function joinName() {
}
var P1 = new Account("Nathan", "Smith", "SA001", 500);
var P2 = new Account("John", "Smith", "SA002", 1500);
</script>
</body>
</html>
First of all I have to point out that your methods wont work out as is. They need to be declared on your Account class prototype.
Account.prototype.deposit = function(amt) {
...
}
For the issue that you want to output html the absolute easiest method would be
Account.prototype.print = function() {
document.body.innerHTML = JSON.stringify(this);
}
For the issue of combining properties you would do
Account.prototype.joinName = function() {
return this.fname + ‘ ‘ + this.lname;
}
However, if you plan to use that joined name a lot I would just set it in the constructor.
this.joinedName = fname + ‘ ‘ + lname

not able to acces private method through privilaged methods in javascript

Error : undefined error in console, while trying to print age function
var Person = function( myName, myProfession, myage ){
this.name = myName; // Public Variable
this.profession = myProfession;
var age = myage; // Private Variable
this.myAge = function(){ // Privilaged Method
return this.age;
};
};
var syed = new Person('syed azam','developer',20);
console.log(syed + "works fine");
console.log(syed.myAge());
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
What is this.age? You did not encapsulate it correctly:
this.myAge = function(){
return myage;
};
Note that you don't have to use var age = myage;. DEMO.

Javascript: Modify an object from a pointer

I'm making a digital library with three classes: Library, Shelf & Book. Shelves have their contents as an array of books. Books have two methods, enshelf and unshelf. When a book gets unshelfed it's supposed to set delete the instance of itself from the shelf it's on and then set it's location property to null. How can I modify the shelf it's sitting on? In the constructor if I change this.location, it will just give that property a new value instead of modifying the variable it points to. I feel like this is really simple and I'm overlooking something super basic.
var _ = require('lodash');
//books
var oldMan = new Book("Old Man and the Sea", "Ernest Hemingway", 0684801221);
var grapes = new Book("The Grapes of Wrath", "John Steinbeck", 0241952476);
var diamondAge = new Book("The Diamond Age", "Neal Stephenson", 0324249248);
//shelves
var shelf0 = new Shelf(0);
var shelf1 = new Shelf(1);
//libraries
var myLibrary = new Library([shelf0, shelf1], "123 Fake Street");
//these need to accept an unlimited amount of each
function Library(shelves, address) {
this.shelves = shelves; //shelves is an array
this.address = address;
this.getAllBooks = function() {
console.log("Here are all the books in the library: ");
for (var i = 0; i < this.shelves.length; i++) {
console.log("Shelf number " + i + ": ");
for (var j = 0; j < this.shelves[i].contents.length; j++) {
console.log(this.shelves[i].contents[j].name);
}
}
}
}
function Shelf(id) {
this.id = id;
this.contents = [];
}
function Book(name, author, isbn) {
this.name = name;
this.author = author;
this.isbn = isbn;
this.location = null;
this.enshelf = function(newLocation) {
this.location = newLocation;
newLocation.contents.push(this);
}
this.unshelf = function() {
_.without(this.location, this.name); //this doesn't work
this.location = null;
}
}
console.log("Welcome to Digital Library 0.1!");
oldMan.enshelf(shelf1);
myLibrary.getAllBooks();
oldMan.unshelf();
myLibrary.getAllBooks();
Small issue with your unshelf method, easily remedied:
this.unshelf = function() {
this.location.contents =
_.without(this.location.contents, this);
this.location = null;
}
Consider, however, that shelf and unshelf should be methods of Shelf, and not of Book. Also, if you must have this method, surround it with a guard, like so:
this.unshelf = function() {
if (this.location) {
this.location.contents =
_.without(this.location.contents, this);
this.location = null;
}
}
Couple of small issues:
without works on arrays and returns a copy of the array with the elements removed - the original is untouched. So you need to pass location.contents instead of just location and reassign it back to location.contents.
Also you add the whole book to the Shelf, then try to remove it by name, so it doesn't match and get removed. So just pass this to without:
this.unshelf = function() {
if (this.location) {
this.location.contents = _.without(this.location.contents, this);
this.location = null;
}
}

loop through arrays and output results to html

I've got this method speak(), which takes two arguments. It's a property of the prototype, so multiple objects will use it.
I'd like to grab those values it returns, loop through them, and output them to my html. The part I can't figure out is, how do I target each individual paragraph tag to correspond with the output of each from each of my variables generated results?
Would this require a double loop? I'm lost.
var para = document.querySelectorAll('p');
var speak = function(what, job) {
var whoWhat = this.name + ' says, ' + what,
whoJob = this.name + "'s job is: " + job;
console.log(whoWhat);
console.log(whoJob);
return whoWhat, whoJob;
};
function Peep(name, job) {
this.name = name;
this.job = job;
}
Peep.prototype.speak = speak;
var randy = new Peep('Randy', 'lawyer');
randy.speak('"blahblah"', randy.job);
var mandy = new Peep('Mandy', 'mom');
mandy.speak('"woooooaahhhh"', mandy.job);
Here's a jsfiddle
Check this one - jsFiddle
Keep adding the HTML to a text. And finally add them to the DOM.
var speak = function(what, job) {
var whoWhat = this.name + ' says, ' + what,
whoJob = this.name + "'s job is: " + job;
console.log(whoWhat);
console.log(whoJob);
return "<p>"+whoWhat+", "+whoJob+"</p>";
};
var txt = "";
var randy = new Peep('Randy', 'lawyer');
txt+=randy.speak('"blahblah"', randy.job);
var mandy = new Peep('Mandy', 'mom');
txt+=mandy.speak('"woooooaahhhh"', mandy.job);
document.getElementById('result').innerHTML = txt;
//in HTML add the result node
<body>
<p id='result'>
</p>
</body>
Using JavaScript you can access the DOM (Document Object Model) and can append new elements to existing elements. For example, you could create a new paragraph element and add this paragraph element to an existing div with the id "result". Here is an example:
var appendText = function (text, parentId) {
var para = document.createElement("p");
var node = document.createTextNode(text);
para.appendChild(node);
var parentElement = document.getElementById(parentId);
parentElement.appendChild(para);
}
var speak = function (what, job) {
var whoWhat = this.name + ' says, ' + what,
whoJob = this.name + "'s job is: " + job;
return [whoWhat, whoJob];
};
function Peep(name, job) {
this.name = name;
this.job = job;
}
Peep.prototype.speak = speak;
var randy = new Peep('Randy', 'lawyer');
var randySays = randy.speak('"blahblah"', randy.job);
appendText(randySays[0], "result");
appendText(randySays[1], "result");
var mandy = new Peep('Mandy', 'mom');
var mandySays = mandy.speak('"woooooaahhhh"', mandy.job);
appendText(mandySays[0], "result");
appendText(mandySays[1], "result");
Here is the jsfiddle with the required html: http://jsfiddle.net/stH7b/2/. You can also find more information on how to append a paragraph to the DOM here: http://www.w3schools.com/js/js_htmldom_nodes.asp

Categories