Assignment task4: Add the listStudents() method
In this task, you will add a method to the Bootcamp class that lists all the registered students' names and emails.
Create a method in the Bootcamp class named listStudents().
In the method body:
Check if the this.students array is empty.
If so, console.log() the message:
No students are registered to the ${this.name} bootcamp.
Then return the boolean value of false.
Otherwise, console.log() the line:
The students registered in ${this.name} are:
Then iterate through the entire this.students array and console.log() the name and email of each student on one line for each student. See the Testing section below for an example of the expected output.
You can do this with the for...of loop.
Finally, return the boolean value of true.
Testing code:
const runTest = (bootcamp, student) => {
const attemptOne = bootcamp.registerStudent(student);
const attemptTwo = bootcamp.registerStudent(student);
const attemptThree = bootcamp.registerStudent(new Student("Babs Bunny"));
if ( attemptOne && !attemptTwo && !attemptThree) {
console.log("TASK 3: PASS");
}
bootcamp.registerStudent(new Student('Babs Bunny', 'babs#bunny.com'));
if (bootcamp.listStudents()) {
console.log("TASK 4: PASS 1/2");
}
bootcamp.students = [];
if (!bootcamp.listStudents()) {
console.log("TASK 4: PASS 2/2");
}
};
My code below does not work. Please help me review. Thanks
class Bootcamp {
constructor(name, level, students = []){
this.name = name;
this.level = level;
this.students = students;
}
registerStudent(studentToRegister){
if (!studentToRegister.name || !studentToRegister.email) {
console.log("Invalid name or email");
return false;
} else if(this.students.filter(s => s.email === studentToRegister.email).length) {
console.log("This email is already registered");
return false;
} else {
this.students.push(studentToRegister)
console.log(`Successful registration ${studentToRegister.name} ${Bootcamp.name}`)
return true;
}
}
listStudent(registerStudent){
if(this.students.length === 0)
{
console.log(`No students are registered to the ${this.name} bootcamp.`);
return false;
}
else
{
console.log(`The students registered in ${this.name} are:`);
for(const registerStudent of this.students)
{
console.log("Name:" + registerStudent[name] + "Email:" + registerStudent[email]);
return true;
}
}
}
}
listStudents() {
if (this.students.length == 0) {
console.log("No students are registered to the ${this.name} bootcamp");
return false;
} else {
console.log("The students registered in ${this.name} are:");
for (let student of this.students) {
console.log(`Name: ${student.name} Email: ${student.email}`);
}
return true;
}
}
}
Related
I have a method that makes http get request from a url, this method gets called from multiple components, each call is making the http request, so I have stored the result in an array to return the array on the second call and not make the http request again, but it is not returning the array, its making the http request again.
Here is my code:
export class ProductsService {
public currency: string = '';
public products: Product[];
// Initialize
constructor(private http: HttpClient, private toastrService: ToastrService) {
}
// Get Products
public getProducts(): Observable<Product[]> {
return this.getAllProducts();
}
private getAllProducts(): Observable<Product[]> {
if (this.products) {
return of(this.products);
} else {
return this.getIp().pipe(
switchMap(country => {
this.currency = this.getCurrency(country);
return this.http.get('http://localhost:8080/products/getAllProducts?currency=' + this.currency).pipe(
map((res: any) => {
this.products = res;
return this.products;
})
);
})
);
}
}
private getIp() {
return this.http.get<any>(('http://ip-api.com/json/?fields=countryCode')).pipe(
map(r => r.countryCode)
);
}
private getCurrency(country: string): string {
let currency;
if (country === 'JO') {
currency = 'JOD';
} else if (country === 'AE') {
currency = 'AED';
} else if (country === 'SA') {
currency = 'SAR';
} else if (country === 'GB') {
currency = 'GBP';
} else if (country === 'DE') {
currency = 'EUR';
} else if (country === 'KW') {
currency = 'KWD';
} else if (country === 'EG') {
currency = 'EGP';
} else {
currency = 'USD';
}
return currency;
}
}
what am I doing wrong here why the method is making the http request again after the first call, shouldn't the array be filled and returned?
Please note that the components are calling the method getProducts() in the ngOnInit()
You are returning the get which is an observable. Each time these methods are called they begin a new subscription to the endpoints.
public getProducts(): Observable<Product[]> {
return this.getAllProducts();
}
private getAllProducts(): Observable<Product[]> {
if (this.products) {
return of(this.products);
} else {
return this.getIp().pipe(
switchMap(country => {
this.currency = this.getCurrency(country);
return this.http.get('http:/ <== this is an observable
You need a service to sync this stuff.
I have an example service for simple state that I used to sync URL params for many components on StackBlitz that may help you.
I am using the angular typeahead:-
<label>USER</label>
<input type="text" name="user" ng-model="a.user" autocomplete="off" typeahead="a for a in getAllUsers($viewValue);getAllStaffs($viewValue)" typeahead-loading="loadingCodes" typeahead-no-results="noResults">
My directive Code:-
scope.getAllUsers = function(key) {
var obj = {
"key": key
}
if (key.length >= 2) {
return ApiServices.getAllUsers(obj).then(function(response) {
return response.data.map(function(item) {
return item;
});
});
} else {
return false;
}
};
scope.getAllStaffs = function(key) {
var obj = {
"key": key
}
if (key.length >= 2) {
return ApiServices.getAllStaffs(obj).then(function(response) {
return response.data.map(function(item) {
return item;
});
});
} else {
return false;
}
};
There are two functions:- One is used for fetching users name and one is used for fetching staffs name. I want both this functions to call on the same input.
But the typeahead is getting list of staff members only. Is there any way to get both list populated in the same input.
Define a new function that does both requests and merges the results.
scope.getAllNames = function(key) {
var obj = {
"key": key
}
function extract(resp) {
return resp.data.slice(0)
}
if (key.length >= 2) {
return Promise.all([
ApiServices.getAllUsers(obj).then(extract),
ApiServices.getAllStaffs(obj).then(extract)
])
.then(function(results) {
return [].concat.apply([], results)
});
} else {
return false;
}
}
I need to push a JSON object to AngularJS and need to check before if the value for one of the objects exist. I need to overwrite the data.
$scope.setData = function(survey, choice) {
keepAllData.push({
'surveyId': survey.id,
'choiceId': choice.id
});
console.log(keepAllData);
toArray(keepAllData);
alert(JSON.stringify(toArray(keepAllData)));
$scope.keepAllDatas.push({
'surveyId': survey.id,
'choiceId': choice.id
});
var items = ($filter('filter')(keepAllDatas, {
surveyId: survey.id
}));
}
function toArray(obj) {
var result = [];
for (var prop in obj) {
var value = obj[prop];
console.log(prop);
if (typeof value === 'object') {
result.push(toArray(value));
console.log(result);
} else {
result.push(value);
console.log(result);
}
}
return result;
}
If the survey id exists in keepalldata, I need to change the recent value with choiceid. Is it possible to do with AngularJS?
Try with this: Before pushing data you have to check if the survey id exists or not. If it exists you have to update choice with the corresponding survey id, otherwise you can push directly.
$scope.setData = function(survey, choice) {
var item = $filter('filter')(keepAllData, {
surveyId: survey.id
});
if (!item.length) {
keepAllData.push({
'surveyId': survey.id,
'choiceId': choice.id
});
} else {
item[0].choiceId = choice.id;
}
console.log(keepAllData);
}
Demo
$scope.keepAllDatas = [];
$scope.setData = function(survey, choice) {
if($scope.keepAllDatas.length == 0) {
$scope.keepAllDatas.push({'surveyId':survey.id,'choiceId':choice.id});
}
else {
var items = ($filter('filter')( $scope.keepAllDatas, {surveyId: survey.id }));
for (var i = items.length - 1; i >= 0; i--) {
// alert(items[i].surveyId);
if(items[i].surveyId == survey.id) {
console.log($scope.keepAllDatas.indexOf(survey.id));
$scope.keepAllDatas.splice($scope.keepAllDatas.indexOf(survey.id),1);
console.log("Removed data")
}
}
$scope.keepAllDatas.push({'surveyId':survey.id, 'choiceId':choice.id});
console.log( $scope.keepAllDatas)
// alert(items[0].surveyId);
}
}
I have a registration dialog where when the user enters username and password I need to check the DB whether the user is present
or not. But when I am validation for the same my call does not hold back until I get the results from the server.
After searching for a while I got to know about callbacks. So I have added a call back inside this.isUser method.
And it is successful. But now doRegistration method is not synchronous with the isUser method.
How to make all my calls synchronous?
this.doRegistration = function(uname, pwd, confirmPwd) {
if(this.isUser(uname)) {
return "USER_EXISTS";
} else {
saveUser(uname, pwd);
return "SUCCESS";
}
};
this.isUser = function(username) {
var users = new Array();
getAllUsers('param', function(response) {
users = response;
console.log(users.length);
for(i = 0; i < users.length; i++) {
if(users[i].username === username) {
return true;
}
}
return false;
});
};
function getAllUsers(param, callback) {
loginFactory.AllUsers.query(function(response) {
if(response != undefined && response.length > 0) {
callback(response);
}
});
}
You may rewrite the code like following:
this.doRegistration = function(uname, pwd, confirmPwd, callBack) {
this.isUser(uname,function(flag) {
if(flag){
callBack("USER_EXISTS");
}
else {
saveUser(uname, pwd, function(err,result){
if(err){
callBack("SAVING_FAILED");
}
else {
callBack("SUCCESS");
}
});
}
});
};
this.isUser = function(username,callBack) {
var users = new Array();
getAllUsers('param', function(response) {
users = response;
console.log(users.length);
for(i = 0; i < users.length; i++) {
if(users[i].username === username) {
callBack(true);
}
}
callBack(false);
});
};
function saveUser(userName, pwd, callBack){
//code to save user
//chek for error in saving
if(err){
callBack(err,null)
}
else {
callBack(null, "success")
}
}
function getAllUsers(param, callback) {
loginFactory.AllUsers.query(function(response) {
if(response != undefined && response.length > 0) {
callback(response);
}
});
}
You may also define saveUser as a function with callback. Here it wont wait for saveUser method to complete.
I have create a filter but this filter is not working with array inside array.
'http://plnkr.co/edit/oygy79j3xyoGJmiPHm4g?p=info'
Above plkr link is working demo.
app.filter('checkboxFilter', function($parse) {
var cache = { //create an cache in the closure
result: [],
checkboxData: {}
};
function prepareGroups(checkboxData) {
var groupedSelections = {};
Object.keys(checkboxData).forEach(function(prop) {
//console.log(prop);
if (!checkboxData[prop]) {
return;
} //no need to create a function
var ar = prop.split('=');
//console.log("ar is - "+ar);
if (ar[1] === 'true') {
ar[1] = true;
} //catch booleans
if (ar[1] === 'false') {
ar[1] = false;
} //catch booleans
/* replacing 0 with true for show all offers */
if(ar[0]=='SplOfferAvailable.text'){
ar[1]='true';
}else{
}
//make sure the selection is there!
groupedSelections[ar[0]] = groupedSelections[ar[0]] || [];
//at the value to the group.
groupedSelections[ar[0]].push(ar[1]);
});
return groupedSelections;
}
function prepareChecks(checkboxData) {
var groupedSelections = prepareGroups(checkboxData);
var checks = [];
//console.log(groupedSelections);
Object.keys(groupedSelections).forEach(function(group) {
//console.log("groupedSelections- "+groupedSelections);
//console.log("group- "+group);
var needToInclude = function(item) {
//console.log("item- "+item);
// use the angular parser to get the data for the comparson out.
var itemValue = $parse(group)(item);
var valueArr = groupedSelections[group];
//console.log("valueArr- "+valueArr);
function checkValue(value) { //helper function
return value == itemValue;
}
//check if one of the values is included.
return valueArr.some(checkValue);
};
checks.push(needToInclude); //store the function for later use
});
return checks;
}
return function(input, checkboxData, purgeCache) {
if (!purgeCache) { //can I return a previous 'run'?
// is the request the same as before, and is there an result already?
if (angular.equals(checkboxData, cache.checkboxData) && cache.result.length) {
return cache.result; //Done!
}
}
cache.checkboxData = angular.copy(checkboxData);
var result = []; // this holds the results
//prepare the checking functions just once.
var checks = prepareChecks(checkboxData);
input.every(function(item) {
if (checks.every(function(check) {
return check(item);
})) {
result.push(item);
}
return result.length < 10000000; //max out at 100 results!
});
cache.result = result; //store in chache
return result;
};
});
above code is for check box filter.
when i click on checkbox called "Availability" it does not filter the result.
Please help me out.
Thanks.
I think that the way you are navigating through json is wrong because if you put in this way it works
"Location": "Riyadh",
"AvlStatus": "AVAILABLE"
"Rooms": {.....
You have to go in some way through Rooms and right now I think you're not doing that