-
Couldn't load subscription status.
- Fork 0
Code review of Group 2 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: review-base
Are you sure you want to change the base?
Conversation
And clarify command presentation
And minor fixes
navbar, register and login
Pre proxy closes DeimosA#37
Pre app router#16
…you are logged in or not
… and current user
and moved service and models into shared folder. Also generated mypage component
Super deals page 59
…qually Make login and register great again
behaviour subject does this
Product details component 24
and show correct price for percent sales
search, filter and sort
…le#57 Edit product and sale
list concatenation 🤷
Revert "Merge branch 'master' into dev"
| create: function (req, res) { | ||
| // The body should contain an array of objects with productId and quantity | ||
| if (!req.body instanceof Array) | ||
| return res.badRequest({error: 'Expected an array of objects with productId and quantity'}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use braces with all multi-line blocks. (https://github.com/airbnb/javascript#blocks--braces)
| let orderQuantity = {}; | ||
|
|
||
| for (let product of req.body) { | ||
| // Check valid product format and store key: value for easy quantity lookup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use iterators. Use .forEach instead. (https://github.com/airbnb/javascript#iterators--nope)
| }); // Order callback end | ||
| }); // Product callback end | ||
| }); // User callback end | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General feedback.
In order to be maintainable, this function create needs some improvements. The function is too large. With 88 lines, it is so long that the developer found it necessary to comment each block ending. That is a bad sign.
Use Promises instead of callbacks
In this functions, there are three callbacks inside of each other. That can quickly create a mess - and all of your code disappears out of the screen to the right, because of all the indentation. This problem is largely solved if you make use of Promises.
Use forEach, map, filter and reduce instead of iterators
Javascript has excellent built-in functions for dealing with arrays - amongst them are forEach, map, filter and reduce. Learning those functions and when to use them would create more readable and maintainable code.
Split the function into several smaller functions
Every function should ideally fit into one computer screen, and should only do one thing. This function could be split into several smaller functions. One for finding the user. One for finding the products. One for calculating the price of a product based on sales. And one for creating an order. Then the next developer who sees this code would easier understand what is going on here.
Use more brackets
Many if statements in this functions does not use brackets. While somewhat frowned upon, dropping the brackets in small one-liners is ok - but it is important that the entire statement is on one line. Otherwise it can be easy to create confusing code, like this:
if (x > 3)
x = 5;
y = 2;| * Give a user admin privileges | ||
| */ | ||
| makeAdmin: function (req, res) { | ||
| User.update(parseInt(req.params.id), {isAdmin: true}).exec(function (err, user) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if req.params.id is not an int?
| * Remove a users admin privileges | ||
| */ | ||
| removeAdmin: function (req, res) { | ||
| User.update(parseInt(req.params.id), {isAdmin: false}).exec(function (err, user) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if req.params.id is not an int?
| isAdmin: boolean; | ||
|
|
||
| constructor(user) { | ||
| if (user.hasOwnProperty('id') && user.hasOwnProperty('email') && user.hasOwnProperty('isAdmin')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is really being checked here? With this check, you could still pass inn undefined for id, email and isAdmin, and this would return true.
const user = {
id: undefined,
email: undefined,
isAdmin: undefined
};
user.hasOwnProperty('id') && user.hasOwnProperty('email') && user.hasOwnProperty('isAdmin')
> true| } else { | ||
| url = '/api/product'; | ||
| return this.http.post<ProductModel>(url, product); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ternary statements can be useful sometimes.
const url = product.id ? `/api/product/${product.id}` : '/api/product';
return this.http.post<ProductModel>(url, product);| let url = '/api/user/login'; | ||
| return this.http.post(url, body) | ||
| .map(result => new UserModel(result)) | ||
| .do(result => this.userLoggedIn(result)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does do do? I have never seen it before in this context.
| this.router.navigate(['/']); | ||
| }else if(statusCode === 401){ | ||
| // handle username or password wrong | ||
| alert("Wrong username or password."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better solution could have been made here.
| // Iterate over our products and calculate price | ||
| for (let product of products) { | ||
|
|
||
| let quantity = orderQuantity[product.id]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not check for quantity > 0. Numerical values received from users should always be validated.
Also does not do a strict check on the quantity, allowing arrays and null to be used.
| required: true, | ||
| minLength: 8, | ||
| maxLength: 72, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not do strict type checking, allowing ["a", "b", "c", "d", "e", "f", "g", "h"] as a password, which turns into "a,c,b,d,e,f,g,h" when logging in. It won't happen from a well-written client, but can be abused.
| }); | ||
| } | ||
|
|
||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Data validation in database structures
While it is quite convenient to use Sails for a lot of the validation, it does not catch obvious type coercions that happen in Javascript. Most notably is the coercion of arrays into strings.
Apart from that, most of the data validation works as expected.
| } | ||
|
|
||
| private findItem(id: number){ | ||
| return this.cart.filter((e) => e.productId == id)[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fetching the first element of an array regardless of its size puts burden on outside code, and should generally be avoided.
| this.searchTerm, | ||
| this.sort, | ||
| this.minPrice | ||
| ).subscribe(products => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When is this callback unsubscribed?
Please don't merge or close
We're trying out Github as a code review tool. This pull request is an attempt at achieving that, by letting us comment on code. By using the first commit with all skeletons in place, we make it easier to see what was written by the group members and not part of the automatic skeletons of Angular and Sails.