Skip to content

Conversation

@ThokozaniNqwili
Copy link

No description provided.

app.ts Outdated
}
}

let resizeTimeout: number;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another global variable

app.ts Outdated
$('#page').empty();
$('#page').append(`Showing record: ${firstNumber} - ${count}`);
$('#loader').hide()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove space

app.ts Outdated
}
if (records[r].includes(inputValue)) {

lastRow.css('background-color', '#DDC0B4'); // hightlights the searched row

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove spaces around

app.ts Outdated
}
fetchColumns()

async function adjustRowsByScreenHeight(): Promise<number> { // calculates the number of rows that can fit the screen

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this an async?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a mistake because of my understanding, I will work on it.

app.ts Outdated
if (firstNumber < 0) {
firstNumber = 0;
lastNumber = firstNumber + (calculatedRows - 1);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the else on the same line as the } please

app.ts Outdated
lastNumber = firstNumber

}
if (!lastNumber) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and the else does exactly the same

app.ts Outdated
@@ -0,0 +1,199 @@
import { ajax, css } from "jquery";
var firstNumber: number = 0;
var lastNumber: number;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to have a default

index.html Outdated
</table>


<script src="app.js"></script>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can move script tag into the head tag

Copy link

@DevinFledermaus DevinFledermaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments as initial changes

app.ts Outdated
@@ -0,0 +1,183 @@
import { ajax, css } from "jquery";
let firstNumber: number = 0;
let lastNumber: number = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to set the variable and the type, either give a type, or set it

app.ts Outdated
if (!recordCount.ok) {
throw new Error('Failed to fetch record count');
}
const data = await recordCount.json()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const data = await recordCount.json()
const data = JSON.parse(recordCount)

app.ts Outdated
.then((columns: string[]) => {
const colArray = columns;

for (let c = 0; c < colArray.length; c++) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use for..of loop please

app.ts Outdated
if (calculatedRows === 0) {
lastNumber = firstNumber
}
if (firstNumber < 0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if and move in the same line as }

app.ts Outdated
if (firstRow) { // checks if the first row exists
const cells = firstRow.querySelectorAll("td");
const firstRecord: string[] = [];
cells.forEach((cell) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather make use of a for..of loop, even a for loop is fine, but for of is preferred

app.ts Outdated
import { ajax, css } from "jquery";
let firstNumber = 0;
let lastNumber = 0;
let backend: string = "http://localhost:2050";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try for 2 global variables

app.ts Outdated
} catch (error) {
throw new Error('Error fetching the record count')
};
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for ; after declaring a function

app.ts Outdated
Comment on lines 55 to 56
const jsonText = await response.text();
const columns: string[] = await JSON.parse(jsonText);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const jsonText = await response.text();
const columns: string[] = await JSON.parse(jsonText);
const columns: string[] = JSON.parse(response.text());

app.ts Outdated
};
};

function adjustRowsByScreenHeight() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to use the function keyword and provide a return type

app.ts Outdated
async function displayRecords(): Promise<void> {
try {
$('#loader').show();
let count = await fetchRecordCount() - 1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still not done

app.ts Outdated
Comment on lines 100 to 108
try {
const response = await fetch(`${backend}/records?from=${from}&to=${to}`);
if (!response.ok) {
throw new Error("Sorry, there's a problem with the network");
}
return response.json();
} catch (error) {
throw new Error('Error fetching records from server');
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the async anymore, and can remove the try and catch

Suggested change
try {
const response = await fetch(`${backend}/records?from=${from}&to=${to}`);
if (!response.ok) {
throw new Error("Sorry, there's a problem with the network");
}
return response.json();
} catch (error) {
throw new Error('Error fetching records from server');
};
return fetch(`${backend}/records?from=${from}&to=${to}`)
.then(res => {
if (!res.ok) {
throw "Sorry, there's a problem with the network";
}
return res.json();
}).catch(err => {
throw 'Error fetching records from server ' + err;
});

app.ts Outdated
Comment on lines 1 to 2
import { ajax, css } from "jquery";
class GlobalVariables {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please leave an empty line between your imports and class definitions.

app.ts Outdated
Comment on lines 6 to 8
resizeTimeout = 0;
//fetches the number of records from localhost
fetchRecordCount(): Promise<number> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please leave and empty line between your class attributes and your functions.

app.ts Outdated
Comment on lines 3 to 6
firstNumber = 0;
lastNumber = 0;
backend = "http://localhost:2050";
resizeTimeout = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a type to each of these variables.

app.ts Outdated
lastNumber = 0;
backend = "http://localhost:2050";
resizeTimeout = 0;
//fetches the number of records from localhost
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to a javadoc style comment. and instead of saying localhost, rather say "the backend attribute on this class"

app.ts Outdated
//fetches the number of records from localhost
fetchRecordCount(): Promise<number> {
return fetch(`${this.backend}/recordCount`)
.then((res) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either remove the () around the res, or specify the correct type for res

app.ts Outdated
let inputValue = $('#searchInput').val() as number;
$('#page').empty();
//calls to calculate the range once button is clicked
await updateRecordsAndResize(inputValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can throw an error, please catch it and handle it.

app.ts Outdated
rightArrow();
})
$('.arrow-left').on('click', () => {
leftArrow();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can throw and error, please catch it and handle it.

style.css Outdated
}

.loader-spinner {
border: calc(200px / 10) solid #97694F;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calc is really really really bad, please don't use it.

style.css Outdated
justify-content: center;
align-items: center;
z-index: 9999;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something happend with your formatting here.

style.css Outdated
height: 100px;
animation: spin 2s linear infinite;
background-color: #f7e7ce;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting issue here.

Copy link

@CelesteNaude CelesteNaude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that all events that the user can fire off is debounced, i.e. search, resize, and buttons.

app.ts Outdated
@@ -0,0 +1,265 @@
import { ajax, css } from "jquery";

class Myclass {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the class into a separate file.

app.ts Outdated
Comment on lines 168 to 170
const halfRange = Math.floor(calculatedRows / 2);
myClass.firstNumber = Math.max(0, inputValue - halfRange);
myClass.lastNumber = Math.min(recordCount, myClass.firstNumber + (calculatedRows - 1));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, you show the searched record in the middle of the grid and highlight it. In IMQS we show the most relevant record we're searching for at the top of the grid without formatting. But you can still keep the formatting because it's cool.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Soooooo... I can't find an example that @CelesteNaude is talking about... I can only find two examples where we do it the way that you are doing it. But that has a lot to do with the fact that most of the time we filter instead of search.

(BTW @CelesteNaude, the two places is user-management, where we highlight and scroll to the user you just edited and the grids on the map, when you click on something on the map, and highlight and scroll to the feature you clicked on)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This I remember from the advice that was given to me for my own onboarding project, weird.

app.ts Outdated
/** determines te value in the last row */
const lastID = parseFloat(lastRecord[0]);
/** checks if the last value is within range */
if (0 <= lastID && lastID <= (recordCount)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need the () around recordCount

app.ts Outdated
}
/** determines te value in the first row */
const firstID = parseFloat(firstRecord[0]);
if (0 <= firstID && firstID <= (recordCount)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

app.ts Outdated
@@ -0,0 +1,230 @@
import { ajax, css } from "jquery";

const myClass = new Myclass();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global variables are bad, please remove them.

app.ts Outdated
@@ -0,0 +1,230 @@
import { ajax, css } from "jquery";

const myClass = new Myclass();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also... please... please give it a better name... This name creates the idea that the Dev that made it isn't even aware of what it is used for.

app.ts Outdated
const myClass = new Myclass();

/** Initializes the table head */
function createTable(): Promise<string[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right name for your function. It seems to be adding headings to a dom element with the class head. Which does not sound like it is "creating a table".

I also don't know how I feel about returning an array of strings? Or anything for that matter. In my head a create* function is either creating something and returning it, or creating something somewhere and returning a reference to it. With the "returning a reference" being completely optional, and I your case I don't think you should be returning anything.

app.ts Outdated
}

/** calculates the number of rows that can fit the screen */
const calculatingRows = (): number => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... why make a constant variable that points to a function? You can just make a function. Please change this to just be a normal function.

app.ts Outdated
}
})
.catch(err => {
throw new Error('Error occured while resizing' + err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the last line of defense, you have to handle the error.

myClass.ts Outdated
@@ -0,0 +1,48 @@
class Myclass {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned, please rename the class

myClass.ts Outdated
Comment on lines 2 to 3
firstNumber: number = 0;
lastNumber: number = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two values are not being used in this class... Maybe you forgot to add methods using them? Or maybe they should not be in this class?

myClass.ts Outdated
firstNumber: number = 0;
lastNumber: number = 0;
backend: string = "http://localhost:2050";
resizeTimeout: number = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This value is not being used in this class... Maybe you forgot to add methods that uses it? or maybe it should not be in this class?

myClass.ts Outdated
}

/** fetches records from backend */
fetchRecords(from: number, to: number): Promise<any[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use any

resizeTimeout: number = 0;

/** fetches the number of records from backend */
fetchRecordCount(): Promise<number> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You saaaaay number... yet you return res.json()... something is not adding up.

app.ts Outdated
if (this.firstNumber < 0) {
this.firstNumber = 0;
} else {
this.firstNumber = this.firstNumber;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting this.firstNumber equal to this.firstNumber? Sjoe 😢 Is the else then even necessary?

app.ts Outdated
});

$('#searchInput').on('keydown', (event) => {
if (event.key === 'e' || event.key === 'E') {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rather make use of regex to stop the user from entering anything besides a digit.

app.ts Outdated
Comment on lines 243 to 245
if (inputValue.includes('.')) {
$('#searchInput').val(inputValue.replace('.', ''));
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With regex then these checks won't be necessary since you know the user could only type in digits.

app.ts Outdated
}

/** calculates the number of rows that can fit the screen */
calculatingRows(): number {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
calculatingRows(): number {
getNumberOfRows(): number {

With a function name like that it is more descriptive of what it does. calculatingRows sounds like a boolean check like isCalculatingRows? Rather give it the verb of what it is going to do. I mean, since this function returns something how about get? How it got it is not maybe important. It calculated it, someone else calculated it? We just want the number of rows.

app.ts Outdated
Comment on lines 164 to 172
const lastID = parseFloat(cells[0].textContent || "");
// checks if the last value is within range
if (0 <= lastID && lastID <= this.recordCount) {
// calculates the first number of the page
this.firstNumber = lastID + 1;
const calculatedRows = this.calculatingRows();
// calculates the last number of the page
this.lastNumber = this.firstNumber + (calculatedRows - 1);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I understand this function, you only need this part of the logic. You don't have to go and find the last child. You know what it is because you set it in this.lastNumber, right? Replace lastID with this.lastNumber and then you can remove the rest and just call this.updateAndDisplayRecords afterward.

app.ts Outdated
Comment on lines 185 to 190
const firstID = parseFloat(cells[0].textContent || "");
if (0 <= firstID && firstID <= this.recordCount) {
const calculatedRows = this.calculatingRows();
this.lastNumber = firstID - 1;
this.firstNumber = this.lastNumber - (calculatedRows - 1);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment to the rightArrow function's comment. You don't have to rely on the HTML. You are the point of truth. Also, maybe a more descriptive function name instead of rightArrow and leftArrow? I mean, what does the function do? Navigate back and forth. Verbs instead.

style.css Outdated
.showRecords {
top: 0.8%;
right: 0;
padding: 1rem;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather make use of px instead of rem

app.ts Outdated
if (inputValue !== '') {
errorMessage = 'Failed to search, reload the page and search again';
$('#loader').show();
this.searchRecordsAndResize();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not call this outside of updateAndDisplayRecords.
Call both this.searchRecordsAndResize and then this.updateAndDisplayRecords in your search input event?

Copy link
Contributor

@FritzOnFire FritzOnFire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always try and handle errors as late as possible, otherwise your code will not be very portable and reusable.

app.ts Outdated
this.firstNumber = 0;
this.lastNumber = 0;
this.recordCount = 0;
this.initialize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not recommend calling functions that can throw errors in a constructor... You could technically still handle the errors, but the rest of your code would think everything went fine, when it very much did not.

Please call this initialize after creating a new instance of RecordManager

app.ts Outdated
Comment on lines 16 to 27
this.createTableHeader();
dataManager.fetchRecordCount()
.then(count => {
this.recordCount = count - 1;
this.updateAndDisplayRecords();
this.recordEventHandlers();
this.handleResize();
})
.catch(err => {
alert('Error fetching and displaying the table records, reload the page');
throw err;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... two things.

  1. Returning a promise makes catching errors much much easier for the calling function, so i would recommend always doing it. BUT

  2. Here you are kicking off two async function calls that do not depend on each other, which is beautiful :) This is a great way to speed up an app, but the calling function still needs to be able to handle the error of the function that you are not waiting for. And so now I will be breaking my own rule about not commenting exact code on an onboarding project. This is how you can wait on multiple async functions at the same time:

Suggested change
this.createTableHeader();
dataManager.fetchRecordCount()
.then(count => {
this.recordCount = count - 1;
this.updateAndDisplayRecords();
this.recordEventHandlers();
this.handleResize();
})
.catch(err => {
alert('Error fetching and displaying the table records, reload the page');
throw err;
});
let p: Promise<void>[] = [];
p.push(this.createTableHeader());
let frcp = dataManager.fetchRecordCount()
.then(count => {
this.recordCount = count - 1;
this.updateAndDisplayRecords();
this.recordEventHandlers();
this.handleResize();
})
.catch(err => {
alert('Error fetching and displaying the table records, reload the page');
throw err;
});
p.push(frcp);
return Promise.all(p);

app.ts Outdated
Comment on lines 25 to 26
alert('Error fetching and displaying the table records, reload the page');
throw err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

???

So you handle the error... and then you throw it anyway meaning that you have to handle it again later?

Please do not handle the error here, as who ever is calling initialize needs to know that we failed to initialize and they need to react accordingly.

app.ts Outdated
Comment on lines 39 to 40
alert('Error creating table heading');
throw err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as before about handling and then throwing again.

app.ts Outdated
Comment on lines 67 to 68
alert('Error to fetch and display records, reload the page');
throw err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as before about handling and then throwing again.

app.ts Outdated
$('#btnSearch').on('click', (event) => {
event.preventDefault();
this.searchRecordsAndResize();
this.updateAndDisplayRecords();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to handle the error being thrown by updateAndDisplayRecords

dataManager.ts Outdated
if (!res.ok) {
throw 'Failed to fetch record count';
}
return res.json();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return res.json();
return res.text();

dataManager.ts Outdated
return res.json();
})
.then(totalRecords => {
if(typeof totalRecords !== 'number'){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice touch :) Now I kinda feel bad for asking you to not use json.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very creative way to hide the fact that you are using a global variable called backend. While there is nothing wrong with using static, and even making a class like this, as there truly is a time and a place for everything, its just unfortunately not in this on boarding project. Please remove all the static labels in this class.

This is basically as bad as turning off asynchronous requests in javascript for this project (I have only seen it once, and I am unable to find out how to do it, but I know it exists).

index.html Outdated
<p>Hello</p>
<div id="loader">
<div class="loader-spinner"></div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your formatting is a bit off here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants