Angular - search-page

Θα δημιουργήσουμε το search-page component, το οποίο περιέχει τα αποτελέσματα της αναζήτησης του χρήστη. Όταν ο client θέλει τα προϊόντα της αναζήτησης, κάνει ένα HTTP GET request στο url http://localhost:8080/api/search?keyword=shampoo&page=0&order=asc και το Spring Boot θα του επιστρέφει τα προϊόντα ανά εξάδα. Ουσιαστικά πραγμαποιούμε το ερώτημα "Select prod from Product prod where prod.name like '%shampoo%'".

Spring Boot

Δημιουργούμε τα SearchService και SearchServiceImpl.

                
                        package springeshop.service;

                        public interface SearchService{

                          ...
                          Page ProductPage findBySearchTerms(String[] searchTerms, int page, List<Brand> brands , List<double[]> priceRanges, String order);
                          int findSearchProductsNumberByRange(String[] searchTerms, double min, double max, List<Brand> brands);
                          int findSearchProductsNumberByBrand(String[] searchTerms, Brand brand, List<double[]> priceRanges);
                          List<Brand> findSearchBrands(String[] searchTerms);
                        } 
                
            
                
                            package springeshop.service;

                            @Service("searchService")
                            @Transactional
                            public class SearchServiceImpl implements SearchService{

                              @Autowired
                              private  EntityManager entityManager;
                        }
                
            

Υλοποιούμε τη μέθοδο Page ProductPage findBySearchTerms(String[] searchTerms, int page, List<Brand> brands , List<double[]> priceRanges, String order);

                    
                                  @Override
                                  public Page ProductPage findBySearchTerms(String[] searchTerms, int page, List<Brand> brands , List<double[]> priceRanges, String order);
    
                                  CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
                                  CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
                                  Root<Product> productsRoot = criteriaQuery.from(Product.class);
                    
                

Δημιουργούμε συνθήκες του WHERE, "prod.name like '%' + :searchTerm + '%' ", "prod.price between :range1 and :range2" και "prod.brand = :brand"

                    
                                  List<Predicate> searchPredicatesList = new ArrayList<>();
                                  List<Predicate> brandPredicateList = new ArrayList<>();
                                  List<Predicate> priceRangePredicateList = new ArrayList<>();

                                  if(searchTerms.length > 0){
                                    for(String term : searchTerms){
                                      searchPredicatesList.add(criteriaBuilder.like(productsRoot.get("name"), "%" + term +"%"));
                                    }
                                  }

                                  if(!brands.isEmpty()){
                                    for(int i=0; i < brands.size(); i++){
                                      brandPredicateList.add(criteriaBuilder.equal(productsRoot.get("brand"), brands.get(i)));
                                    }
                                  }
    
                                  if(!priceRanges.isEmpty()){
                                    for(double[] range : priceRanges){
                                      priceRangePredicateList.add(criteriaBuilder.between(productsRoot.get("price"), range[0], range[1]));
                                    }
                                  }

                                  Predicate[] searchPredicatesArray = new Predicate[searchPredicatesList.size()];
                                  searchPredicatesList.toArray(searchPredicatesArray);

                                  Predicate[] brandsPredicateArray = new Predicate[brandPredicateList.size()];
                                  brandPredicateList.toArray(brandsPredicateArray);
    
                                  Predicate[] priceRangePredicateArray = new Predicate[priceRangePredicateList.size()];
                                  priceRangePredicateList.toArray(priceRangePredicateArray);

                                  Predicate brandsPredicate = criteriaBuilder.or(brandsPredicateArray);
                                  Predicate priceRangePredicate = criteriaBuilder.or(priceRangePredicateArray);
                                  Predicate searchPredicate = criteriaBuilder.or(searchPredicatesArray);
                    
                

Δημιουργούμε το κατάλληλο ερώτημα, ανάλογα με το αν είναι επιλεγμένα τα φίλτρα ή όχι

                    
                                  if(!brands.isEmpty() && !priceRanges.isEmpty()){
                                    criteriaQuery.where(searchPredicate, brandsPredicate, priceRangePredicate);
                                  }else if(brands.isEmpty() && priceRanges.isEmpty()){
                                    criteriaQuery.where(searchPredicate);
                                  }else{
                                    if(brands.isEmpty()){
                                      criteriaQuery.where(criteriaBuilder.and(searchPredicate, priceRangePredicate));
                                    else{
                                      criteriaQuery.where(criteriaBuilder.and(searchPredicate, brandsPredicate));
                                   }
                                  }
                    
                

Ταξινομούμε τα προϊόντα με βάση την παράμετρο order, βρίσκουμε τον αριθμό των συνολικών προϊόντων και επιστρέφουμε την κατάλληλη σελίδα

                    
                                  Order orderCriterion = order.equals("asc") ? criteriaBuilder.asc(productsRoot.get("price")) : criteriaBuilder.desc(productsRoot.get("price"));
                                  criteriaQuery.orderBy(orderCriterion);

                                  ProductPage productPage = new ProductPage();
                                  int totalProducts = entityManager.createQuery(criteriaQuery).getResultList().size();
                                  int startProductPosition = page * 6;
                                  productPage.setTotalElements(totalProducts);
                                  productPage.setTotalPages(getProductPages(totalProducts));

                                  List<Product> wantedProducts = entityManager.createQuery(criteriaQuery).setFirstResult(startProductPosition).setMaxResults(6).getResultList();
                                  productPage.setContent(wantedProducts);
                                  productPage.setNumber(page);
                                  productPage.setNumberOfElements(wantedProducts.size());
                                  return productPage;
                    
                

Δημιουργούμε τoν SearchApiController στο πακέτο springeshop.controller

                
                            package springeshop.controller;

                            @RestController
                            @RequestMapping("/api")
                            public class SearchApiController{
                        
                               public static final  Logger logger = LoggerFactory.getLogger(SearchApiController.class);

                               @Autowired
                               private  BrandService brandService;
    
                               @Autowired
                               private  SearchService searchService;
    
                               @Autowired
                               private  InventoryService inventoryService;

                               @Autowired
                               private  ProductImageService productImageService;

                                ...
                
            

Προσθέτουμε τη μέθοδο στον CategoryApiController.

                
                           @RequestMapping(value = "/search", method = RequestMethod.GET)
                           public ResponseEntity<?> getSearchProducts(@RequestParam((value = "keyword") String[] keywords, 
                                         @RequestParam( (value = "brand", required = false) int String[] brands, 
                                         @RequestParam( (value = "range", required = false) int String[] ranges, 
                                         @RequestParam( (value = "page", required = true) int page, 
                                         @RequestParam((value = "order", required = true) String order){

                           ProductPage productPage = new ProductPage();
                           List<double[]> priceRangeList = new ArrayList<>();
                           List<Brand> brandPredicateList = new ArrayList<>();

                          if(brands != null){
                            brandList = brandService.findSpecificBrands(brands);
                          }

                          if(ranges != null){
                            for(String range : ranges){
                              rangeValues[0] = getRangeMin(range);
                              rangeValues[1] = getRangeMax(range);
                              priceRangeList.add(rangeValues);
                            }
                          }

                           productPage = searchService.findBySearchTerms(keywords, page, brandList, priceRangeList, order);

                           if(productPage.getContent().isEmpty()){
                             logger.error("No products found.");
                             return new ResponseEntity<>(HttpStatus.NO_CONTENT);
                           }

                           addImagesAndQuantityToProducts(productPage.getContent());

                           return new ResponseEntity<>(productPage, HttpStatus.OK);

                           }
                
            
search-page component

Δημιουργούμε το component search-page και το search service.

                    
                                ng generate component category-page
                    
                
                    
                                ng generate service service
                    
                

Θα χρησιμοποιήσουμε τη μέθοδο getSearchProducts() του SearchService, για να πραγματοποιήσουμε το HTTP αίτημα και να πάρουμε το προϊόντα.

Search Service

Κάθε φορά που αλλάζει ο χρήστης αλλάζει όρους αναζήτηση ή επιλέγει φίλτρα, παίρνουμε τις τιμές τους και πραγματοποιούμε το HTTP αίτημα, για να πάρουμε τα προϊόντα της αναζήτησης.

search-page.component.ts

Search Page Ts

search-page.component.html

Search Page Html

search-page.component.css

Search Page Css
Τελική εμφάνιση σελίδας
Category Page Image