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
}
Related
Still can't understand my mistake with this code.
All what I want it - via prompt get all list of users (name / surname)
function UserList() {
let users = [];
while (true) {
let response = prompt('Please, enter your name surname?');
if (response == null) {
alert('cancel');
break;
}
users.push(response.split(' '));
}
return users;
}
function User() {
this.name = userList[0];
this.surname = userList[1];
this.regDate = new Date;
for (i = 0; i < userList.length; ++i) {
console.log('Name: ' + this.name + ' Surname: ' + this.surname + '. Date of registration : ' + this.regDate)
}
}
let userList = new UserList();
let user = new User();
And I faced with a misunderstanding why I cant get first word of prompt despite I put users.push (response.split(' ')).
userList [0] - shows first index of array instead first word.
And second I want to get all list of users in console.log but instead it I get the same string depending on length of array
userList[0] in the function User will return an array: ['name', 'surname'].
To get the first name for example, you need to use this.name = userList[i][0]
function UserList() {
let users = [];
while (true) {
let response = prompt('Please, enter your name surname?');
if (response == null) {
alert('cancel');
break;
}
users.push(response.split(' '));
}
return users;
}
function User() {
for (var i = 0; i < userList.length; ++i) {
this.name = userList[i][0];
this.surname = userList[i][1];
this.regDate = new Date;
console.log('Name: ' + this.name + ' Surname: ' + this.surname + '. Date of registration : ' + this.regDate)
}
}
let userList = new UserList();
let user = new User();
You are pushing an array in an other array, so your index is not correct (array looks like this: [["firstname", "lastname"]]). You could spread the items when pushing using the spread operator (...), you could also flatten the array using flat().
Also when creating a date, use new Date().
function UserList() {
let users = [];
while (true) {
let response = prompt('Please, enter your name surname?');
if (response == null) {
alert('cancel');
break;
}
users.push(...response.split(' ')); // flatten
}
return users;
}
function User() {
this.name = userList[0];
this.surname = userList[1];
this.regDate = new Date(); // ()
console.log('Name: ' + this.name + ' Surname: ' +
this.surname + '. Date of registration : ' + this.regDate)
}
let userList = new UserList();
let user = new User();
Using flat()
return users.flat();
Edit
I actually understood the question wrong (thought you only wanted 1 user), the other answer should be correct and makes more sense.
UserList shouldn't be a constructor. It should just be a function that returns an array of names.
You shouldn't be iterating over the list of users within User. You should then be iterating over the array creating one new User on each iteration which should be generated from a constructor. You can just pass in each name from the array and build an new object.
function getNames() {
const users = [];
while (true) {
const response = prompt('Please, enter your first and last names');
if (response == null) break;
users.push(response.split(' '));
}
return users;
}
// Pass in a user name from the array as an argument
// It's array so we can destructure the first and last name
// immediately
function User([first, last]) {
this.first = first;
this.last = last;
this.regDate = new Date();
this.message = `Name: ${this.first}. Surname: ${this.last}. Date of registration: ${this.regDate}.`;
}
// Iterate over the array generated by `getUsers`
// and for each name create a new user.
for (let name of getNames()) {
console.log(new User(name));
}
Additional documentation
Destructuring assignment
This seems simple but I'm banging against a wall. My code gets weights, accesses an object array to get a value then calculates a result using that value * weight. But accessing the object doesn't work with a variable.
function calc(){
var gender;
if(document.getElementById("male").checked){
gender = "mensList";
} else if (document.getElementById("female").checked){
gender = "womensList";
} else {
alert("Please select a gender");
return false;
}
var kg = parseInt(document.getElementById("bwKg").value);
var grams = parseFloat(document.getElementById("bwGrams").value);
var bw = parseFloat(kg + grams);
var lifted = parseFloat(document.getElementById("liftWeight").value);
var theValue = womensList[bw]; // This works
var theValue = mensList[bw]; // This also works
var theValue = gender[bw]; // This doesn't work
var theValue = gender + "[\"" + bw + "\"]" // Nor this
var result = theValue * lifted;
document.getElementById("result").textContent = result;
}
var womensList = {
40.0: "1.4936",
40.1: "1.4915",
40.2: "1.4894",
40.3: "1.4872",
40.4: "1.4851",
// ......... etc
150.7: "0.7691",
150.8: "0.7691",
150.9: "0.7691"
};
var mensList = {
40.0: "1.3354",
40.1: "1.3311",
40.2: "1.3268",
40.3: "1.3225",
40.9: "1.2975",
// ......... etc
205.7: "0.5318",
205.8: "0.5318",
205.9: "0.5318"
};
In your code you are setting a gender to string not variable.
if(document.getElementById("male").checked){
gender = "mensList";
} else if (document.getElementById("female").checked){
gender = "womensList";
}
Should be
if(document.getElementById("male").checked){
gender = mensList;
} else if (document.getElementById("female").checked){
gender = womensList;
}
Here is your problem :
if(document.getElementById("male").checked){
gender = "mensList"; //gender now contains a string only..
} else if
Since gender contains a mere string, this will not work:
var theValue = gender[bw]; // This doesn't work
What you should be doing instead is :
if(document.getElementById("male").checked){
gender = mensList; //now gender contains an array provided mensList is defined beforehand ..
}
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>
I was messing with some js on codecadamy and got a bit sidetracked trying to make something work.
In essence I was creating a few objects that are loaded into a controller object and set as properties of it with two functions that print the properties and compare a string to the name property of each object in the controller.
I noticed I can do it if I make the objects in the prototype style and specify a normal function to handle setting the properties like so:
var friends = {};
friends.setUp = function() {
this.friends = [];
for(var i in arguments) {
arguments[i].setUp();
this.friends.push(arguments[i]);
}
};
friends.list = function() {
for(var i in this.friends) {
console.log(this.friends[i]);
}
};
friends.search = function(name) {
for(var i in this.friends) {
if(this.friends[i].firstName === name) {
return this.friends[i];
}
}
};
var bill = {};
bill.setUp = function() {
this.firstName = "Bill";
this.lastName = "Gates";
this.number = "(206) 555-5555";
this.address = ['One Microsoft Way','Redmond','WA','98052'];
};
var steve = {};
steve.setUp = function() {
this.firstName = "Steve";
this.lastName = "Jobs";
this.number = "(206) 555-5555";
this.address = ['1 Infinite Loop','Cupertino','CA','95014'];
};
var mike = {};
mike.setUp = function() {
this.firstname = "Mike";
this.lastname = "Ryd";
this.number = "(800) 555-5555";
this.address = ['redacted'];
};
friends.setUp(bill, steve, mike);
friends.list();
var result = friends.search("Steve");
console.log(result);
However if I do it with constructors It does not work, example:
function bill() {
this.firstName = "Bill";
this.lastName = "Gates";
this.number = "(206) 555-5555";
this.address = ['One Microsoft Way','Redmond','WA','98052'];
};
function steve() {
this.firstName = "Steve";
this.lastName = "Jobs";
this.number = "(206) 555-5555";
this.address = ['1 Infinite Loop','Cupertino','CA','95014'];
};
function mike() {
this.firstname = "Mike";
this.lastname = "Ryd";
this.number = "(800) 555-5555";
this.address = ['redacted'];
};
function friends() {
this.friends = [];
for(var i in arguments) {
this.friends.push(arguments[i]);
}
};
friends.list = function() {
for(var i in this.friends) {
console.log(this.friends[i]);
}
};
friends.search = function(name) {
for(var i in this.friends) {
if(this.friends[i].firstName === name) {
return this.friends[i];
}
}
};
var bill = new bill();
var steve = new steve();
var mike = new mike();
var friends = new friends(bill, steve, mike);
friends.list();
var result = friends.search("Steve");
console.log(result);
I was wondering if this is a limitation of using constructors or am I messing up the syntax somewhere? Thank you!
This doesn't appear to have anything to do with constructors with an unknown number of arguments, but rather you are not assigning methods on your objects appropriately. They need to be put on the prototype so that they will be inherited by all objects that are created by this particular constructor. So in your code, these:
friends.list = function() {...}
friends.search = function() {...}
needs to be changed to:
friends.prototype.list = function() {...}
friends.prototype.search = function() {...}
Like this:
friends.prototype.list = function() {
for(var i = 0; i < this.friends.length; i++) {
console.log(this.friends[i]);
}
};
friends.prototype.search = function(name) {
for(var i = 0; i < this.friends.length; i++) {
if(this.friends[i].firstName === name) {
return this.friends[i];
}
}
};
Then, this code should work fine:
var bill = new bill();
var steve = new steve();
var mike = new mike();
var friends = new friends(bill, steve, mike);
friends.list();
var result = friends.search("Steve");
console.log(result);
And, then the code works as you would expect here: http://jsfiddle.net/jfriend00/ba4me8ua/
FYI, you'll noticed that I changed the way you iterate through the arguments object items to be more array-like and avoid any chance of getting any non-numeric properties in the iteration.
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;
}
}