Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codeigniter and AngularJS bug: pagination does not work when the application is not in the root directory

I am working on a blog application with Codeigniter 3.1.8 and AngularJS v1.7.8.

The Dashboard of the application is "pure" Codeigniter, with Models, Controllers, and views, while the fronted is made up of JSONs managed and displayed by AngularJS. (I operated this clear separation between back-end and front-end in order to enable "themeing".)

The posts are paginated. On the back-end, in the Posts controller, the posts list looks like this:

private function _initPagination($path, $totalRows, $query_string_segment = 'page') {
  //load and configure pagination 
    $this->load->library('pagination');
    $config['base_url'] = "http://".$_SERVER['HTTP_HOST'] . $path;
    $config['query_string_segment'] = $query_string_segment; 
    $config['enable_query_strings'] =TRUE;
    $config['reuse_query_string'] =TRUE;
    $config['total_rows'] = $totalRows;
    $config['per_page'] = 12;
    if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
        $_GET[$config['query_string_segment']] = 1;
    }
    $this->pagination->initialize($config);

    $limit = $config['per_page'];
    $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;

    return ['limit' => $limit, 'offset' => $offset];
}

public function index() {

  //call initialization method
    $config = $this->_initPagination("/", $this->Posts_model->get_num_rows());

    $data = $this->Static_model->get_static_data();
    $data['pagination'] = $this->pagination->create_links();
    $data['pages'] = $this->Pages_model->get_pages();
    $data['categories'] = $this->Categories_model->get_categories();  

  //use limit and offset returned by _initPaginator method
    $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);

    // All posts
    $this->output->set_content_type('application/json')->set_output(json_encode($data,JSON_PRETTY_PRINT));
}

On the front-end, in AngularJS, I have:

 // All posts
.controller('PostsController', ['$scope', '$http', function($scope, $http){

    //Get current page (?page=2, ?page=3 etc)
    const currPage = window.location.search;

    // Get all the posts on the current page 
    $http.get('api/' + currPage).then(function(response) {

        //Categories
        $scope.categories = response.data.categories;

        // Posts
        $scope.posts = response.data.posts;

        // posts pagination
        $scope.pagination = response.data.pagination;

    });
}])

The problem is that the pagination does not work (the links are pointing to the wrong likne) when the application is not in the root directory (it is at www.examplesite.com/blog, not at www.examplesite.com).

I suppose it has something to do Codeigniter's base_url() but I have not been able to spot the bug and fix it.

How can I fix this issue?

like image 903
Razvan Zamfir Avatar asked Dec 29 '19 21:12

Razvan Zamfir


2 Answers

Take a look at this line:

$config = $this->_initPagination("/", $this->Posts_model->get_num_rows());

This specifies the path as "/", which is passed as $path, so in your function the link path will be

$config['base_url'] = "http://".$_SERVER['HTTP_HOST'] . $path;

which will just put a / at the end of the root URL. You will need to pass the proper suffix at index instead of "/" when not on root.

like image 87
Lajos Arpad Avatar answered Sep 29 '22 19:09

Lajos Arpad


The problem is here:

$config['base_url'] = "http://".$_SERVER['HTTP_HOST'] . $path;

Because $_SERVER['HTTP_HOST'] is always the root without other directory.

You need to use something like:

$config['base_url'] = str_replace("/api/", "/", base_url()) . $path;

But I recomand you to implement the pagination in your front end (Angular) and in CI you need only something like:

public function index($offset, $limit) {
    $data = [];
    $data['count'] = $this->Posts_model->get_num_rows();
    $data['pages'] = $this->Pages_model->get_pages();
    $data['categories'] = $this->Categories_model->get_categories();  
    $data['posts'] = $this->Posts_model->get_posts($limit, $offset);

    $this->output->set_content_type('application/json')->set_output(json_encode($data,JSON_PRETTY_PRINT));
}
like image 29
Doru D. Avatar answered Sep 29 '22 19:09

Doru D.