1

I am creating an Angular app (version 8) that I have nested within a WordPress site. I am trying to make a request to a plugin to get some data from the database. Using Angular's HTTPClient I get a 400 Bad Request. I think that this has to do with not being able (or at least not knowing how) to pass the action up to WP in order to get the AJAX code to run properly.

I can use jQuery's $.get() function and get a proper response, but then I am having difficulty passing the data from my service to my component.

I'm very rusty on my Angular chops, so I am sure I'm not doing something right. Any suggestions or pointers would be much appreciated!!!

The plugin's AJAX code:

   //UTIL Functions
    public function get_categories(){
        global $wpdb;
        $cat_sql = "SELECT * FROM {$wpdb->prefix}" . SELF::CATEGORY_TABLE;
        return $wpdb->get_results($cat_sql);
    }

    public function ajaxGetCategories(){
        $prods = $this->get_categories();
        if($prods !== FALSE){

            //NEED TO ASSIGN THE RETURNED OBJECT TO AN ARRAY AND PASS THAT DOWN

            $prodArray = [];
            for($i = 0; $i < count($prods); $i++){
                $prodArray[$i]['p_index'] = $prods[$i]->p_index;
                $prodArray[$i]['product_name'] = $prods[$i]->product_name;
                $prodArray[$i]['product_sections'] = $prods[$i]->product_sections;
                $prodArray[$i]['product_imgID'] = $prods[$i]->product_imgID;
            }

            wp_send_json_success($prodArray);
        }else {
            wp_send_json_error("Error!"); 
        }
        //return $prods;
        wp_die();
    }
        // front end ajax calls
        add_action( 'wp_ajax_get_products', array($this,'ajaxGetCategories') );
        add_action( 'wp_ajax_nopriv_get_products', array($this,'ajaxGetCategories') );

Angular Service:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import * as $ from 'jquery';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private params: object = {
    'action' : 'get_products'
  }
  private post_url: string = 'https://MYCOOLSITE.COM/wp-admin/admin-ajax.php';

  public products = [];


constructor( ) {  
 }

public  getProducts() { 

 $.post(this.post_url, this.params, function(data){

    if(data.success == true){

      var prod = [];
      for(var i = 0; i < data.data.length; i++){
        prod[i] = [];
        console.log("data 1: " + data.data[i] );

        for(var prop in data.data[i]){
          prod[i][prop] = data.data[i].prop;
        }
      }
      return prod;
    } else {
      // @TODO - ADD ERROR HANDLING
    }

  });
}

Angular Component:

import { Component,OnInit } from '@angular/core';
import {ProductService} from './product.service';
import { Observable } from 'rxjs/Observable';



@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
  providers: [ProductService]
})
export class AppComponent implements OnInit{

  title = 'Choose a product.';

  constructor(private productService: ProductService){ 
    this.productService.getProducts();
     }


  ngOnInit() {  

  }

}

As for the code as it sits, I can get all the data to print to the console in the service, but it never makes it to the component.

I've noticed in the $.get() in the service that it's not returning prod, nor can I pass any of the values to this.products (due to scope issues). But I would at least think that it would return prod out of the function.... (?)

I played around with trying to get prod to be an observable, but that was even worse luck. I think that my best bet would be to use http.get() from Angular, since that passes an observable automatically, but I haven't been able to figure out how to pass the ajax action name to the plugin to make that successful. All my Googling has pulled up is using the WP API, which doesn't do me any good.

1 Answer 1

1

Please try this

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import * as $ from 'jquery';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private params: object = {
    'action' : 'get_products'
  }
  private post_url: string = 'https://MYCOOLSITE.COM/wp-admin/admin-ajax.php';

   products = new BehaviorSubject<any>([]);
  productsList = this.products.asObservable();


constructor(private http: HttpClient ) {  
 }

public  getProducts() { 

 this.http.post<any>(this.post_url, this.params).subscribe(data=> {

    if(data.success == true){

      this.products.next(data.data)
    } else {
      // @TODO - ADD ERROR HANDLING
    }

  });
}

On component

import { Component,OnInit } from '@angular/core';
import {ProductService} from './product.service';
import { Observable } from 'rxjs/Observable';



@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
  providers: [ProductService]
})
export class AppComponent implements OnInit{

  title = 'Choose a product.';

  constructor(private productService: ProductService){ 
    this.productService.getProducts();
     }


  ngOnInit() {  
    this.productService.productsList.subscribe(response => {
        console.log(response);
      })
  }

}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! This was definitely what I needed to get in the right direction. I added this but was still getting a back request on the AJAX call. I did some more digging and eventually found out that PHP doesn't like how Angular serializes the data getting sent, so WP wasn't finding the "action" that I was sending over. I had to add the params as a query string and change the content type to "application/x-www-form-urlencoded" but now it works like a charm!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.