Prosba o pomoc w wytknieciu bledow

0

Na weekendzie zostalem poproszony o napisanie prostego API w ramach testu programistycznego. Zadanie polegalo na polaczeniu dwoch plików JSON odpowiednim polem i posortowanie samochodow i modeli w zaleznosci od wybranych filtrow. Front-end do uzywania API byl za punkty bonusowe.
Jesli ktos zechcialby rzucic okiem i pomóc co moznaby poprawic w kodzie (test oblalem), nie dostalem konkretnego feedbacku a zapewne nie zdaje sobie sprawy z wielu bledow i "zlych praktyk".

(function() {
	document.addEventListener("DOMContentLoaded", function() {
		var cars = [
		  {
		    "id": "00000001",
		    "modelId": "ac5c3b18-6804-4e34-ac19-cf3d693f5cdf",
		    "mileage": 25000,
		    "registration": "PS128DE",
		    "transmission": "Manual",
		    "owners": 1,
		    "description": "<title>Car advert</title><h1>Car ad title</h1><p>Lorem ipsum dolor</p>",
		    "price": 13250,
		    "photos": [
			...
		    ]
		  },
		  {
		    "id": "00000002",
		    "modelId": "7ee87de1-a30f-4666-9741-726c9facbba7",
		    "mileage": 95000,
		    "registration": "LS05DTR",
		    "transmission": "Manual",
		    "owners": 2,
		    "description": "<title>Car advert</title><h1>Car ad title</h1><p>Lorem ipsum dolor</p>",
		    "price": 6000,
		    "photos": [
			...
		    ]
		  },
		  {
		    "id": "00000003",
		    "modelId": "5905c84b-4a70-47c9-be56-e814553b3015",
		    "mileage": 12000,
		    "registration": "LD58UBQ",
		    "transmission": "Manual",
		    "owners": 1,
		    "description": "<title>Car advert</title><h1>Car ad title</h1><p>Lorem ipsum dolor</p>",
		    "price": 18000,
		    "photos": [
			...
		    ]
		  },
		  {
		    "id": "00000004",
		    "modelId": "5905c84b-4a70-47c9-be56-e814553b3015",
		    "mileage": 45000,
		    "registration": "LD58UBQ",
		    "transmission": "Automatic",
		    "owners": 2,
		    "description": "<title>Car advert</title><h1>Car ad title</h1><p>Lorem ipsum dolor</p>",
		    "price": 12000,
		    "photos": [
			...
		    ]
		  }
		];
		var models = [
		  {
		    "modelId": "ac5c3b18-6804-4e34-ac19-cf3d693f5cdf",
		    "co2Emmissions": 124,
		    "mpg": "54.3",
		    "enginePower": 69,
		    "engineSize": 1229,
		    "fuelType": "Petrol"
		  },
		  {
		    "modelId": "7ee87de1-a30f-4666-9741-726c9facbba7",
		    "co2Emmissions": 230,
		    "mpg": "54.3",
		    "enginePower": 185,
		    "engineSize": 2259,
		    "fuelType": "Petrol"
		  },
		  {
		    "modelId": "5905c84b-4a70-47c9-be56-e814553b3015",
		    "co2Emmissions": 165,
		    "mpg": "54.3",
		    "enginePower": 130,
		    "engineSize": 1798,
		    "fuelType": "Diesel"
		  }
		];
		var getData = new QueryData();
		var filterSet = [];
		var result = [];
		var resultMsg = document.getElementById("resultMsg");

		//merging two json objects before use
		function mergeJSON(dest, source, byField) {
			for(var j=0;j<cars.length;j++) {
				var tmp = cars[j][byField];
				for(var i=0;i<models.length;i++) {
					if(tmp == models[i][byField]) {
						for(prop in models[i]) {
							if(cars[j].hasOwnProperty(prop)) {}
							else {
								cars[j][prop] = models[i][prop];
							}
						}
					}
				}
			}
		}
		//printing out cars object
		function printCars(cars) {		
			resultMsg.innerHTML = "";
			if(result.length>0) {
				for(var j=0;j<cars.length;j++) {
					for(prop in cars[j]) {
						resultMsg.innerHTML += prop + ':' + cars[j][prop] + '<br>';
					}
					if(j!=cars.length-1) {
						resultMsg.innerHTML += '<hr>';
					}
				}
			}
			else if(result.length==0) {
				resultMsg.innerHTML = "No results were found meeting criteria";
			}
		}
		//filtering function, removes from result array those cars that do not meet given criteria
		function filter(filter) {
			switch(filter) {
				case "firstOwner": {
					if(getData.firstOwner == 'on') {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].owners != 1) {
								result.splice(x,1);
							}
						}
					}
				} break;
				case "fuelType": {
					if(getData.fuelType == 'diesel') {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].fuelType != 'Diesel') {
								result.splice(x,1);
							}
						}
					}
					else if(getData.fuelType == 'petrol') {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].fuelType != 'Petrol') {
								result.splice(x,1);
							}
						}
					}
				} break;
				case "priceMin": {
					if(getData.priceMin != "") {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].price<getData.priceMin) {
								result.splice(x,1);
							}
						}
					}
				} break;
				case "priceMax": {
					if(getData.priceMax != "") {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].price>getData.priceMax) {
								result.splice(x,1);
							}
						}
					}
				} break;
				case "engineSize": {
					if(getData.engineSize != 'all') {
					var eSMin = -1;
					var eSMax = -1;
						switch(getData.engineSize) {
							case "0": {
								eSMin=0;
								eSMax=999;
							} break;
							case "1": {
								eSMin=1000;
								eSMax=1399;
							} break;
							case "2": {
								eSMin=1400;
								eSMax=1699;
							} break;
							case "3": {
								eSMin=1700;
								eSMax=1999;
							} break;
							case "4": {
								eSMin=2000;
								eSMax=2999;
							} break;
							case "5": {
								eSMin=3000;
								eSMax=99999;
							} break;
						}
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].engineSize<eSMin || result[x].engineSize>eSMax) {
								result.splice(x,1);
							}
						}					
					}
				} break;
				case "transmission": {
					if(getData.transmission == "manual") {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].transmission!='Manual') {
								result.splice(x,1);
							}
						}
					}
					else if(getData.transmission == 'automatic') {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].transmission!='Automatic') {
								result.splice(x,1);
							}
						}
					}
				} break;
				case "mileageMin": {
					if(getData.mileageMin != "") {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].mileage<getData.mileageMin) {
								result.splice(x,1);
							}
						}
					}
				} break;
				case "mileageMax": {
					if(getData.mileageMax != "") {
						for(var x=result.length-1;x>=0;x--) {
							if(result[x].mileage>getData.mileageMax) {
								result.splice(x,1);
							}
						}
					}
				} break;
				default: {
					alert("Unknown filter.");
				}
			}
			if(result == "") {
				resultMsg.innerHTML += "No results were found meeting criteria.";
			}
			return result;
		}
	 	function availableFilters() {
			var formElems = document.getElementsByTagName("form")[0].elements;
			if(formElems!=null) {
				for(var d=0;d<formElems.length;d++) {
					if(formElems[d].type == 'number' || formElems[d].type == 'select-one' || formElems[d].type == 'radio' ||
					formElems[d].type == 'checkbox' || formElems[d].type == 'text') {	
						filterSet.push(formElems[d].name);
					}
				}
			}
			else {
				alert("Couldn't find any form elements");
			}
			// make sure we have only unique values in a filters array
			filterSet = filterSet.filter(function(item, pos) {
	  			return filterSet.indexOf(item) == pos;
			});
			// console.log("number of filters after unique checking: " + filterSet.length);
		}
		function showFilters(filterSet) {
			if(filterSet.length!=0) {
				for(var c=0;c<filterSet.length;c++) {
					console.log('filterSet(' + c + ') :' + filterSet[c]);
				}
			}
			else {
				alert("no filters to show!");
			}
		}
		/*
			Checks if any filters were set and if so then apply filters 
		*/
		function filterCars(filterSet = null) {
			if(filterSet == null) {
				resultMsg.innerHTML = "No filters were passed";
			}
			else {
				for(var f=0;f<filterSet.length;f++) {
					if(filter(filterSet[f]) == "") {
						return 0;
					}
				}
			}
		}
		function prepareForm() {
			var form = document.getElementsByTagName('form')[0];
			if(form.addEventListener) {	//modern browsers
				form.addEventListener('submit', function(e) {
					// getRequest(form.getAttribute('action'));
					// run();
				}, false);	
			}
			else if(form.attachEvent) {	//old IE
				form.attachEvent('onsubmit', function(e) {
					// e.preventDefault();
					// getRequest('index.php');
					// run();
				});	
			}
		}
		function initialize() {
			//JSON objects that will be merged together and used as a source of cars
			mergeJSON(cars,models,"modelId");
			//create a 'copy' of cars object that can't be modified
			result = JSON.parse(JSON.stringify(cars));
			availableFilters();
			filterCars(filterSet);
		}
		//prepareForm() need to be always executed before 'run()'
		// prepareForm();
		initialize();
		function run() {
			printCars(result);
			console.log(result);
		}
		run();
	//---------- if the form has been submitted -------------------------------------------------------------------------------
	});
}());

0

Nadrzędną radą czystego kodu jest DRY.
Przyjrzyj się

if(getData.fuelType == 'diesel') {
	for(var x=result.length-1;x>=0;x--) {
		if(result[x].fuelType != 'Diesel') {
			result.splice(x,1);
		}
	}
}
else if (getData.fuelType == 'petrol') {
	for (var x = result.length - 1; x >= 0; x--) {
		if (result[x].fuelType != 'Petrol') {
			result.splice(x, 1);
		}
	}
}	

po co powtarzać kod jak można to wszystko spakować w jedną funkcję?

function spliceFuel(getData, result, fuelType) {
	if(getData.fuelType == fuelType) {
		for(var x=result.length-1;x>=0;x--) {
			if(result[x].fuelType != fuelType) {
				result.splice(x,1);
			}
		}
	}
}
// a potem wywołujesz
spliceFuel(getData, result, 'diesel');
spliceFuel(getData, result, 'petrol');

Po drugie: formatowanie, spacje itp.

0

Jak dokładnie brzmiała treść zadania?

0

Treść zadania

0

Pisze z tel i nie wstawiło mi załącznika Hmm może teraz

0

@LudwikJ No ale przecież nie wystawiłeś żadnego API, rozwiązanie jest niezgodne z treścią zadania. Zamiast zrobić backend za pomocą REST API (np w Node.js) zrobiłeś wszystko po stronie frontu.

0

Hmm w Node.js raczej wiedzieli, ze nie napisze, bo nie znam jeszcze. Czyli jeśli wystawiłbym na widok z zewnątrz funkcje zwracające wynik w zależności od parametrów filtrowania to by wystarczyło? Dodam, ze nie mam doświadczenia komercyjnego a jedynie uczę się po godzinach z zamiarem osiągnięcia poziomu wystarczającego żeby dostać pierwsza prace.

1

W zadaniu wyraźnie chcieli backend, jak interesuje cię tylko front to trzeba bylo:
A) nie podejmować się zadania,
B) wyraźnie ustalić inny zakres zadania z rekruterem

A co by wystarczyło, to przecież pytanie do rekrutera, skąd ty się urwałeś, że na forum o to pytasz? :D

PS
Kod jest bardzo słabej jakości, może wieczorem napiszę kilka wskazówek.

0

Rekruter wyraźnie szukał kogoś od wszystkiego za niska płace, napisali to nawet jako jeden z bonusów dla żartu w ogłoszeniu😁 Choć podczas rozmowy telefonicznej uzgodniliśmy ze będę musiał się podszkolić z bibliotek/frameworkow których nie znam. Będę wdzięczny za wszelkie wskazówki, chce popracować nad sobą.

0
Będę wdzięczny za wszelkie wskazówki, chce popracować nad sobą.

Nie poniżaj się tak. Jeśli kod, który napisałeś działą i napisałęś go sam, powinieneś dostać tą prace. W JS jest tak, że jak jest dobrze, to mozna jeszcze lepiej, ale uważam, że jest ok.

1 użytkowników online, w tym zalogowanych: 0, gości: 1