Vue.js Fetch API and PHP generators

Vue.js Fetch API and PHP generators

Created:21 Feb 2020 14:54:20 , in  Web development

By now, Vue.js is an established player among JavaScript frameworks for building user interfaces, and rightly so. It is lightweight, well-documented, easy to learn and incredibly flexible piece of JavaScript code. Considering all this, it is high time to give this framework an important place in a web developer's toolkit, which also means figuring out how to integrate the new piece of machinery to work with other core tools effectively. In this article I look at how to use Vue.js in a (small) project and get it to work seamlessly along PHP.

First thing worth noting is, that Vue.js and PHP live in completely different worlds, mostly unaware of one another's existence. To bridge the gap and ensure smooth communication between the two, a tool capable of conveying message between frontend and backend spaces is needed. One such modern tool is called Fetch API. The API provides means of exchange of data asynchronously between browser and server. It is a modern way of doing AJAX requests and exactly what is needed here. I use Fetch API along Vue.js and PHP in the project described in this article.

Here is an interactive example of what this article is about.

Displaying PHP generated sequences using Vue.js

This article is about building an utility, which I called vuePHPgenerators. The utility generates and displays a fixed number of terms in a user chosen Maths sequence.

Fronted interface of the utility consists of a single HTML select control and a div(ision) element. The latter provides room for displaying backend generated sequence terms, while the former allows to choose a Maths sequence, for which the terms are to be generated.

When user chooses what Maths sequence they want terms for, the requests is passed asynchronously from within Vue.js component to PHP on backend side. A PHP script collects the input data, which consists of a Maths sequence name and number of terms to find, generates the terms and echoes them. Then, the terms in a form of a string get collected in the same Vue.js component, where the request originated from, and written to the screen. In short it is a good old AJAX based trip from frontend to backend and back, but with a twist. The twist is Vue.js component.

In fact, there is one more change to the old ways of doing things here. That is, the asynchronous HTTP request mentioned above is wholly managed by Fetch API and based on fetch function. The rest of this bit stays the old ways. User specified data is still sent to backend using a POST request (GET is easier, but less fun, hence POST here), so with content type header as application/x-www-form-urlencoded, and contents consisting of a long list of url-encoded key, value pairs.

Vue.js componenet powered frontend

Firstly, let's look at the HTML Vue.js works with. It is nice and short.


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Vue PHP Generators</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>

<div id="vuePHPgenerators">
<vuephpgenerators terms="20"></vuephpgenerators>
</div>

</body>
</html>

As can be seen, all interesting stuff is gathered in a container called vuePHPgenerators, which is the tag the main Vue.js instance gets attached to. The instance manages everything within the tag. The internal HTML tag vuephpgenerators is where a Vue.js component with the same name is attached to.

Notice, that vuephpgenerators tag has property "terms" set to 20 in it. The property specifies requested number of terms for user chosen Maths sequence. Its value gets automatically linked to props['terms'] in component vuephpgenerators and is eventually passed to backend through Vue.js component and fetch function of Fetch API.

Normally you would give user a choice with regards to how many sequence terms they want to be returned. I have hard-coded the number to keep the code shorter, and more importantly to show how Vue.js links stuff in a HTML component tag with a props item in a JavaScript component object.

Vue instance and component


// asynchronous request URL
var url = '/vuejs/vuephpgenerators.php';
// component vuephpgenerators
Vue.component('vuephpgenerators',{
  // allowed properties, linked terms item has value 20 now
  props:['terms'],

  // data to work on
  data:function(){
    return {
      // selected sequence name
      selected : '',
      // backend response, initailly empty string
      responseHTML: ''
    }
  },

  methods:{
    // asynchronous method for communicating with backend
    async load(resource){
      // append 
      // not for Internet Explorer (not supported by Internet Explorer)
      var formData = new FormData();
      
      formData.append('sequence',this.selected); 
      formData.append('terms',this.terms); 
      
      // wait till response is received from the server  
      await fetch(url, {
        method: 'POST', // request method
        body: formData, // data to pass to backend script
      // work on Promise returned by fetch 
      }).then((response) => response.text())
      .then((data) => {
        // give Vue.js access to returned data, so that it can insert it as html 
        this.responseHTML = data;
      })
      // deal with potential errors in transport 
      .catch((error) => {
        this.responseHTML = 'Error: '+ error +'. Try again!'
      });
     
    }
  },

  // template with sequence selection control and a container for returned HTML 
  template:'<div> \
    <div v-html="responseHTML"></div> \
    <p>Sequence:<br /> \
    <select v-on:change="load" v-model="selected"> \
      <option value="">Choose ...</option> \
      <option value="fibonacci">Fibonacci</option> \
      <option value="triangular">Triangular Numbers</option> \
      <option value="cosineAndOne">Cos(x) + 1</option> \
    </select> \
    </p> \
  </div>'
});    

// create a Vue.js app
new Vue({
   el: '#vuePHPgenerators'
});

PHP Generators

Now tet's have a look at what's on the backend side.

For the needs of this article I have written class Generators in PHP, which contains a couple of static class methods. The methods generate Maths sequences like Fibonacci and Triangular Numbers sequence, one outputs values of function cos(x)+1 for an angle given in radians. The methods utilize what's know as generators in PHP.

Basically, each time when keyword "yield" shows up in such a method (or just a function), the method returns an object, which is a generator. These generators have methods like current() and next() among others. The methods, when used multiple times, can be employed to generate a sequence of terms.


/**
 * Class: Generators - provides generators for Fibonacci, Triangular Numbers and Cos(x) + 1 
 * Author: S.Wojnowski 
 * Licence: GNU v3
 */

class Generators{

  // Fibonacci sequence
  public static function fibonacci($n){
    $prev = 0;
    $cur = 1;
    for ($i = 0; $i < $n; $i++) {
      yield $cur;
      $temp = $cur;
      $cur = $prev + $cur;
      $prev = $temp;
    }
  }
 
  // triangular numbers 
  public static function triangular($n){
    $current = 1;
    for($i = 1; $i <= $n; $i++ ){
      yield $current;
      $current = $current + $i + 1; 
    }
  }

  // cosine + 1 function with $n terms and and divisor between 1 and 360
  public static function cosineAndOne($n,$divisor = 4){ // PI / 2 radians
    $angle = 0;
    if($divisor <= 0 or $divisor > 360){
      throw new Exception('Divisor must be greater than 0 and less than 361');
    }
    $angleIncrement = (2 * M_PI) / $divisor;
    $current = cos($angle) + 1;

    for($i = 0; $i < $n; $i++ ){
      yield $current;
      $angle = $angle + $angleIncrement;  
      $current = cos($angle) + 1;
   }
 }

}

Asynchronous request backend

When user specifies what Maths sequence they want, their choice is sent over to backend and is dealt with by PHP and the following script:


require_once('generators.php');

if(isset($_POST['terms']) and isset($_POST['sequence'])){
  $output = [];
  $terms = 10; 
  $generator = NULL;
   
  // validate user input
  $sequence = trim(strip_tags($_POST['sequence']));
  $terms = (int)trim(strip_tags($_POST['terms']));
  
  //set max number of terms we can generate 50
  $terms =  $terms > 50 ? 50 : $terms;

  // prepare suitable generator
  switch($sequence){
    case 'triangular':
      $generator = Generators::triangular($terms);
      break;
    case 'cosineAndOne': 
      $generator = Generators::cosineAndOne($terms);
      break;
    default:
      $generator = Generators::fibonacci($terms);
      break;
  }

  // generate and format terms for requested sequence
  for($i = 0; $i < $terms; $i++){
    $term = $generator -> current();
    if($sequence == 'cosineAndOne'){
      $term = sprintf('%.2f',$generator -> current()); 
    }
    $output[] = $term;
    $generator -> next(); 
  }

  // send terms of sequence back to frontend
  echo implode(',',$output);  
  die();
}

Putting it all together

Even though, the code given in this article is a good mixture of PHP, JavaScript and HTML, pretty much all of it resides in a single file called vuephpgenerators.php. The only external part is Generators class, which dwells in generators.php file and gets included right at the top of vuephpgenerators.php.

So, PHP backend code goes on top, HTML follows it, JavaScript bits are placed before closing body tag. Once you have the whole thing working you will certainly want to move different pieces to more suitable places in a filesystem.

Conclusion

One of purposes of the exercise described in this article was to make Vue.js, Fetch API and PHP work in tandem. As you can see, it is both possible and fairly easy to achieve. All three make up a great team. Vue.js nearly makes you forget, that there is such thing as DOM. Fetch API makes sending asynchronous request a breeze, and PHP, well, it makes sure the back(end) is covered ;).

In the next article of this series I look at a somewhat similar example, but one, which instead of using url encoded data, sends a string representation of JSON object to backend. It is a somewhat different game for PHP to play.

This post was updated on 22 Feb 2020 12:54:24

Tags:  JavaScript ,  php ,  vue.js 


Author, Copyright and citation

Author

Sylwester Wojnowski

Author of the above article, Sylwester Wojnowski, enjoys sWWW writing computer code in PHP, JavaScript and BASH, and some other things he wrote more on on the About page of this website.

Copyrights

©Copyright, 2020 Sylwester Wojnowski. This article may not be reproduced or published as a whole or in parts without permission from the author. If you share it, please give author credit and do not remove embedded links.

Computer code, if present in the article, is excluded from the above and licensed under GPLv3.

Citation

Cite this article as:

Wojnowski, Sylwester. "Vue.js Fetch API and PHP generators ." From sWWW - Code For The Web . https://wojnowski.net.pl//main/index/vuejs-fetch-api-and-php-generators