Library.add is not a function error - javascript

I am trying to execute this code:
var addButton = document.querySelector("#add");
var searchButton = document.querySelector("#search");
var titleInput = document.querySelector("#title");
function Book(title) {
this.title = title;
}
function Library() {
this.books = [];
}
Library.prototype.add = function() {
this.add = function(book) {
this.books.push(book);
};
}
var library = new Library();
//Library UI
var libraryUI = {
//Add a new book
addBook: function() {
var listItem = libraryUI.createNewBook(titleInput.value);
Library.add(listItem);
console.log(Library.books);
},
//Create a new book
createNewBook: function(title) {
var book = new Book(title);
return book;
}
};
addButton.addEventListener("click", libraryUI.addBook);
The HTML is here:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Library App</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<h1>Personal Library</h1>
<label for="title">Title: </label>
<input type="text" id="title">
<button id="add">Add</button>
<button id="search">Search</button>
<p id="display"></p>
<script src="js/app.js"></script>
</body>
</html>
What I'm trying to do is press the addButton and the onclick will run the addBook function under the libraryUI object. The title of the book, in an input field, will then be used to create an object with the title of the book in it. I want to add that book to a list of books (an array) in an instance of Library. When I try to do so with the following code, I get the error "Uncaught TypeError: Library.add is not a function". I thought that Library.add is a function.
I added:
var library = new Library();
because I thought I had forgotten to create an iteration of Library, but I still came up with the exact same error. Please help. :)

var addButton = document.querySelector("#add");
var searchButton = document.querySelector("#search");
var titleInput = document.querySelector("#title");
function Book(title) {
this.title = title;
}
function Library() {
this.books = [];
}
Library.prototype.add = function(book) {
this.books.push(book);
}
var library = new Library();
//Library UI
var libraryUI = {
//Add a new book
addBook: function() {
var listItem = libraryUI.createNewBook(titleInput.value);
library.add(listItem);
console.log(library.books);
},
//Create a new book
createNewBook: function(title) {
var book = new Book(title);
return book;
}
};
addButton.addEventListener("click", libraryUI.addBook);
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Library App</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<h1>Personal Library</h1>
<label for="title">Title: </label>
<input type="text" id="title">
<button id="add">Add</button>
<button id="search">Search</button>
<p id="display"></p>
<script src="js/app.js"></script>
</body>
</html>
Shouldn't it be library.add instead of Library.add?
Also: why:
Library.prototype.add = function() {
this.add = function(book) {
this.books.push(book);
};
}
instead of:
Library.prototype.add = function(book) {
this.books.push(book);
}
?
If I change Library.add to library.add and console.log(library.books) I think this does what you want.

Related

my code at first is correct but with this error spread.js.25 I can not see result in the browser

When I inspect the code in the browser this error appears spread.js.25 and I can not find this problem.
I checked the exercise solution, it's the same as my solution ... I don't know much about axios ...
<!DOCTYPE html>
<html lang="en">
<head>
<title>ExercĂ­cio 02</title>
</head>
<body>
<input type="text" name="user">
<button onclick="listRepositories()">Adicionar</button>
<ul></ul>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var listElement = document.querySelector('ul');
var inputElement = document.querySelector('input');
function renderRepositories(repositories) {
for (repo of repositories) {
const textElement = document.createTextNode(repo.name);
const liElement = document.createElement('li');
liElement.appendChild(textElement);
listElement.appendChild(liElement);
}
}
function listRepositories() {
var user = inputElement.value;
if (!user) return;
axios.get('https://api.github.com/users/' + user + '/repos')
.then(function (response) {
renderRepositories(response.data);
})
}
</script>
</body>
</html>
this image is exactly the problem

JavaScript updating a global variable

I am currently not the most experienced in Javascript and I'm trying to learn bit by bit. Anyway... how do I update the balance variable more efficiently?
Currently I believe I am doing this wrong. Also my button does not work on click event.
Anything would be a massive help! Thank you.
// Set global variables
var name;
var balance;
var weed;
// Ask the user his name for his character
name = window.prompt("What is your name?", "Cap'n Grow");
var finalName = document.getElementById('name');
finalName.textContent = name;
// Set the balance to default
balance = 100;
var FinalBalance = document.getElementById('balance');
FinalBalance.textContent = balance;
// Set the balance of weed to default
weed = 10;
var FinalWeed = document.getElementById('gear');
FinalWeed.textContent = weed;
// Sell function
function sellGear() {
var check = window.prompt("Are you sure you want to sell 5 bags?", "Yes");
if (check === 'Yes' && weed >= 5) {
console.log("Transaction was successful!");
// Update the balance
var updBalance = document.getElementById('balance');
updBalance.textContent = balance + 150;
} else {
console.log("Failed!")
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="container">
<header>
<div class="dashboard">
<div id="name"></div>
<div id="balance"></div>
<div id="gear"></div>
<div id="sell">
<button id="sellButton" onlick="sellGear()">Sell?</button>
</div>
</div>
</header>
</div>
</body>
<script src="js/global.js"></script>
</html>
Here is the solution and a suggestion:
Try to use java script code at the end of your HTML.
<html lang="en">
<head>
<title></title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="container">
<header>
<div class="dashboard">
<div id="name"></div>
<div id="balance"></div>
<div id="gear"></div>
<div id="sell">
<button id="sellButton" onclick="return sellGear();">Sell?</button>
</div>
</div>
</header>
</div>
</body>
<script src="js/global.js"></script>
</html>
<SCRIPT>
// Set global variables
var name;
var balance;
var weed;
// Ask the user his name for his character
var name = window.prompt("What is your name?", "Cap'n Grow");
var finalName = document.getElementById('name');
finalName.textContent = name;
// Set the balance to default
var balance = 100;
var FinalBalance = document.getElementById('balance');
FinalBalance.textContent = balance;
var weed = 10;
var FinalWeed = document.getElementById('gear');
FinalWeed.textContent = weed;
// Sell function
function sellGear() {
var check = window.prompt("Are you sure you want to sell 5 bags?", "Yes");
if (check === 'Yes' && weed >= 5) {
console.log("Transaction was successful!");
// Update the balance
var updBalance = document.getElementById('balance');
updBalance.textContent = balance + 150;
} else {
console.log("Failed!")
}
}
</SCRIPT>

Ember action not connecting to method

I am having a problem which should have a simple solution. For some reason my action helper is not connecting to its method.
Here is my JSBin http://jsbin.com/UMaJaM/5/edit
Code is copied below for reference.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Ember template" />
<meta charset=utf-8 />
<title>JS Bin</title>
<script src="http://code.jquery.com/jquery-1.9.0.js"></script>
<script src="http://builds.emberjs.com/handlebars-1.0.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.1.2/ember.js"></script>
</head>
<body>
<div id="main"></div>
</body>
</html>
JavaScript:
var TemplatedViewController = Ember.Object.extend({
templateFunction: null,
context: null,
viewBaseClass: Ember.View,
view: function () {
var controller = this;
var context = this.get('context') || {};
var args = {
template: controller.get('templateFunction'),
controller: controller
};
args = $.extend(context, args);
return this.get('viewBaseClass').extend(args);
}.property('templateFunction'),
appendView: function (selector) {
this.get('view').create().appendTo(selector);
},
appendViewToBody: function (property) {
this.get(property).create().append();
}
});
var template_source = '<button type="button" class="btn" {{action "button"}}>Click</button>';
var MyController = TemplatedViewController.extend({
templateFunction: Ember.Handlebars.compile(template_source),
button: function() {
console.log('hello world');
}
});
var controller = MyController.create();
$(function () {
controller.appendView('#main');
});
You need to create an Ember application. Add this to the beginning of your script:
App = Ember.Application.create();

Creating paragraphs based on user input

I'm having trouble, grabbing the user input, and having the onclick operator create additional paragraphs with each click.
Here is my HTML code.
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Add Paragraph </title>
<meta charset='utf-8' >
<script src="../js/addPara.js" type="text/javascript"></script>
</head>
<body>
<div>
<input type='text' id='userParagraph' size='20'>
</div>
<div id="par">
<button id='heading'> Add your paragraph</button>
</div>
</body>
</html>
Here is Javascript code:
window.onload = function() {
document.getElementById("addheading").onclick = pCreate;
};
function pCreate() {
var userPar= document.createElement("p");
var parNew = document.getElementById('userParagraph').value;
userPar.innerHTML = par;
var area = document.getElementById("par");
area.appendChild(userPar);
}
userPar.innerHTML = par;
should be
userPar.innerHTML = parNew;
In your code:
> window.onload = function() {
> document.getElementById("addheading").onclick = pCreate;
> };
Where it is possible (perhaps likely) that an element doesn't exist, best to check before calling methods:
var addButton = document.getElementById("addheading");
if (addButton) {
addButton.onclick = pCreate;
}
Also, there is no element with id "addheading", there is a button with id "heading" though.
> function pCreate() {
> var userPar= document.createElement("p");
> var parNew = document.getElementById('userParagraph').value;
> userPar.innerHTML = par;
I think you mean:
userPar.innerHTML = parNew;
if you don't want users inserting random HTML into your page (perhaps you do), you can treat the input as text:
userPar.appendChild(document.createTextNode(parNew));
.
> var area = document.getElementById("par");
> area.appendChild(userPar);
> }
Your variable names and element ids don't make a lot of sense, you might wish to name them after the data or function they represent.
I did it and it worked.
<html lang='en'>
<head>
<title>Add Paragraph </title>
<meta charset='utf-8' >
<script>
window.onload = function() {
document.getElementById("heading").onclick = pCreate;
}
function pCreate() {
var userPar= document.createElement("p");
var parNew = document.getElementById('userParagraph').value;
userPar.innerHTML = parNew;
var area = document.getElementById("par");
area.appendChild(userPar);
}
</script>
</head>
<body>
<div>
<input type='text' id='userParagraph' size='20'>
</div>
<div id="par">
<button id='heading'> Add your paragraph</button>
</div>
</body>
</html>```

How to separate a js function?

<!--
Copyright (c) 2008 Google Inc.
You are free to copy and use this sample.
License can be found here: http://code.google.com/apis/ajaxsearch/faq/#license
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
</style>
<script src="https://www.google.com/jsapi?key=ABQIAAAAeEJvEumzGBw8dvenGPw1bRTcyTBaKMmwi780-Sh78Ay3Pg36mBRsO3t_v4eega6kiiiRMl84WG-4eA"></script>
<script type="text/javascript">
google.load('search', '1');
onload = function() {
google.search.Search.getBranding('branding');
//google branding
var searchResultsContainer = document.getElementById('searchResults');
var newsSearch = new google.search.NewsSearch();
newsSearch.setSearchCompleteCallback(this, function() {
if (newsSearch.results && newsSearch.results.length > 0) {
searchResultsContainer.style.display = 'block';
for (var i=0; i<newsSearch.results.length; i++) {
var wrapper = document.createElement('div');
var node = newsSearch.results[i].html.cloneNode(true);
wrapper.className = 'gs-result';
wrapper.appendChild(node);
searchResultsContainer.appendChild(wrapper);
}
}
},null);
newsSearch.execute("sport");
//keyword
}
</script>
</head>
<body>
<div>
<div id="branding" style="float:left;"></div>
<div id="searchResults"></div>
</div>
</body>
</html>
Hi, I want to make a Google news search, the above code runs well. However, I want to separate a js function. I use the following code, but the result shows nothing. How to modify it correctly?
<!--
Copyright (c) 2008 Google Inc.
You are free to copy and use this sample.
License can be found here: http://code.google.com/apis/ajaxsearch/faq/#license
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
</style>
<script src="https://www.google.com/jsapi?key=ABQIAAAAeEJvEumzGBw8dvenGPw1bRTcyTBaKMmwi780-Sh78Ay3Pg36mBRsO3t_v4eega6kiiiRMl84WG-4eA"></script>
<script type="text/javascript">
google.load('search', '1');
function searchcomplete() {
var newsSearch = new google.search.NewsSearch();
if (newsSearch.results && newsSearch.results.length > 0) {
searchResultsContainer.style.display = 'block';
for (var i=0; i<newsSearch.results.length; i++) {
var wrapper = document.createElement('div');
var node = newsSearch.results[i].html.cloneNode(true);
wrapper.className = 'gs-result';
wrapper.appendChild(node);
searchResultsContainer.appendChild(wrapper);
}
}
}
onload = function() {
google.search.Search.getBranding('branding');
//google branding
var searchResultsContainer = document.getElementById('searchResults');
var newsSearch1 = new google.search.NewsSearch();
newsSearch1.setSearchCompleteCallback(this, searchcomplete ,null);
newsSearch1.execute("sport");
//keyword
}
</script>
</head>
<body>
<div>
<div id="branding" style="float:left;"></div>
<div id="searchResults"></div>
</div>
</body>
</html>
A couple of problems here:
function searchcomplete() {
// you create a... uh new empty search here?
var newsSearch = new google.search.NewsSearch();
...
// searchResultsContainer is NOT defined in this scope
searchResultsContainer.style.display = 'block';
...
}
onload = function() {
// this defines searchResultsContainer in the scope of the onload callback,
// but NOT in the global scope
var searchResultsContainer = document.getElementById('searchResults');
...
// the first param is the thing that 'this' in the callback will refer to
// in this case it's the window but you need to change this in order
//to get access to the results
newsSearch1.setSearchCompleteCallback(this, searchcomplete ,null);
...
}
And here's a fixed version:
function searchcomplete() {
// Huh, why this? See below...
if (this.results && this.results.length > 0) {
// get 'searchResultsContainer' here
var searchResultsContainer = document.getElementById('searchResults');
searchResultsContainer.style.display = 'block';
for (var i=0; i < this.results.length; i++) {
var wrapper = document.createElement('div');
....
}
window.onload = function() {
...
// here we supply newsSearch itself as the 'this' so we can access
// its properties inside the callback
newsSearch.setSearchCompleteCallback(newsSearch, searchcomplete ,null);
...
}
You should read up a bit on this and scoping.
I don't know why you tried to do it in this way, but it's the working code:
...
<script type="text/javascript">
google.load('search', '1');
var newsSearch, searchResultsContainer;
function searchcomplete() {
// var newsSearch = new google.search.NewsSearch();
if (newsSearch.results && newsSearch.results.length > 0) {
searchResultsContainer.style.display = 'block';
for (var i=0; i<newsSearch.results.length; i++) {
var wrapper = document.createElement('div');
var node = newsSearch.results[i].html.cloneNode(true);
wrapper.className = 'gs-result';
wrapper.appendChild(node);
searchResultsContainer.appendChild(wrapper);
}
}
}
onload = function() {
google.search.Search.getBranding('branding');
//google branding
searchResultsContainer = document.getElementById('searchResults');
newsSearch = new google.search.NewsSearch();
newsSearch.setSearchCompleteCallback(this, searchcomplete ,null);
newsSearch.execute("sport");
//keyword
}
</script>
...
you don't have to define new variable newsSearch
you should define newsSearch and searchResultsContainer globally.
Happy coding :-)

Categories

Resources