skip to Main Content

I’m trying to process search results from my server. A user writes a search query into a field and the server returns a string containing pairs of article id=article title separated by newline. I’m splitting them around equals sign, but the result is an array with zero. I’m missing something obvious here.

function findArticle(){
    let input=document.getElementById("search")
    let value=input.value
    if(value){
        let request=new XMLHttpRequest()
        request.onreadystatechange=function (){
            if(request.readyState===4){
                let result=request.response
                if(result!==''){
                    let searchResults=document.getElementById('search-results')
                    let split=result.split('/n/')
                    searchResults.innerHTML=''
                    for (const next in split) {
                        let parts=next.split("/=/")
                        console.log(parts)
                        searchResults.innerHTML+="<a href='"+parts[0]+"'>"+parts[1]+"</a>"
                    }
                }
            }
        }
        request.open("GET","article-search.php?query="+value,true)
        request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        request.send()
    }
}

article-search.php

<?php
include_once 'constants.php';
include_once 'functions.php';
$query=$_GET['query'];
$q="SELECT id,title FROM articles WHERE title LIKE '%$query%'";//;"SELECT id,title FROM defaultdb.articles WHERE MATCH (title) AGAINST ('$query')";
$c=defaultMysqlConnection();
$results=executeQuery($c,$q,true);
if($results){
    foreach ($results as $result){
        echo $result['id']."=".$result['title']."n";
    }
}

3

Answers


  1. This has not been tested, but you could modify your PHP to return JSON data.

    $title = $mysqli->real_escape_string($_GET['query']); // Grab title query
    $sql = "SELECT id, title FROM articles WHERE title LIKE ?"; // SQL with parameters
    $stmt = prepared_query($conn, $sql, ['%$title%']); // Execute statement
    $rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); // Fetch an array of rows
    print json_encode($rows); // Return JSON to the client
    

    Now you can parse the response on the client as JSON and simply loop over an array of book objects.

    if (request.readyState === 4 && request.response) {
      const searchResults = document.getElementById('search-results');
      const articles = JSON.parse(request.response);
      articles.forEach(article => {
        const { id, title } = article;
        searchResults.innerHTML += `<a href="${id}">${title}</a>`;
      });
    }
    

    Note: You should always use prepared statements to prevent SQL injection attacks.


    Fetch API

    Instead of using the outdated XHR object, try the newer Fetch API:

    fetch(`article-search.php?query=${value}`, {
      method: 'GET', // Default value, optional
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
    })
      .then(res => res.json())
      .then(articles => {
        const searchResults = document.getElementById('search-results');
        articles.forEach(article => {
          const { id, title } = article;
          searchResults.innerHTML += `<a href="${id}">${title}</a>`;
        });
      })
    
    Login or Signup to reply.
  2. Using slashes in the string you pass to split is incorrect. When splitting on a simple string literal (as opposed to a regular expression), just pass the string literal unaltered.

    let split=result.split('n');
    let parts=next.split('=');
    
    Login or Signup to reply.
  3. There are two issues with your code.

    Separators

    The separator you are trying to split on doesn’t make sense. As mentioned in the comments, you seem to be confusing regular expressions with plain string separators.

    Use "n" and "=" instead of '/n/' and "/=/".
    You could use regular expressions (/n/ and /=/), but those are overkill for this.

    Looping

    You’re trying to loop over an array using for-in. This will loop over the indices of the array; use for-of to loop over elements.

    Why ['0']?

    So, the reason you are getting ['0'] instead of the expected?

    1. The first split operation results in an array, with the data the sole element; it is not split due to the issues with your separator.
    2. You then loop over the sole index of this array, which is the string 0 (because keys are actually always strings).
    3. Calling .split on this returns an array with just it (as there was obviously nothing to split on. Hence the ['0'].
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search