Why am i getting null


#1

HI folks … I’m following a tutorial to try and learn about Ionic & WP Rest API https://audacitus.com/site/2017/03/02/wordpress-rest-api-to-ionic-2-converting-category-id-to-name/

It’s a fairly simple tutorial and i managed to get it working very quickly. But i’m now trying to modify it to work with a Custom Post Type, which for the most part has been successful, with exception to converting category ID to Name.

At this stage i’m just trying to get it to show the listing-category ID as it would for post category in the original tutorial, unfortunately this is just displaying “null”.

I’ve looked at the both the post & listing json is structured and they appear to be identical, i’ve even tried with “location” from listing json and it works, again it appears to be structured exactly the same as listing-category, so i really don’t know were i’m going wrong.

I’m not sure what information you require to further investigate but any help would be greatly appreciated.


#2

Can you post your code for your http calls?


#3

ok so bare in mind i’m an absolute novice and am just following this tutorial, but i’ll post everything i believe to be relevant …

home.html

<ion-header>
    <ion-navbar>
        <button ion-button menuToggle>
            <ion-icon name="menu"></ion-icon>
        </button>
        <ion-title>Home</ion-title>
    </ion-navbar>
</ion-header>

<ion-content padding>  
    <h3>Ionic Menu Starter</h3>
    <ion-list>
    <ion-item *ngFor="let item of items">
      <ion-avatar item-left>
        <img src="assets/icon/favicon.ico">
      </ion-avatar>
      <h2 [innerHTML]="item.title.rendered"></h2>
      <h3>{{item.listing-category | json }}</h3>
      <p [innerHTML]="item.listing_options.tagline_text"></p>
    </ion-item>
  </ion-list>
</ion-content>

home.ts

import { Component } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { NavController } from 'ionic-angular';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  url: string = 'http://competa.life/wp-json/wp/v2/listing';
  categoryUrl : string = 'http://competa.life/wp-json/wp/v2/listing-category';
  categories : any;
  items: any;
 
  constructor(
    public navCtrl: NavController,
    private http: Http
  ) {
    //we've placed loadPosts() in our constructor to run immediately.
    this.loadPosts();
    this.loadCategories();
  }
 
  //Our function to call wordpress
  loadPosts() {
    this.http.get( this.url )
      .map(res => res.json())
      .subscribe(data => {
        this.items = data;
        console.log(data);
      });
  }
 //Our function to load categories
  loadCategories() {
    this.http.get( this.categoryUrl )
      .map(res => res.json())
      .subscribe(data => {
        let categoryArray = {};
 
        data.forEach(function(item){
          categoryArray[item.id] = item.name;
        })
 
        this.categories = categoryArray;
 
        console.log(categoryArray);
      });
  }
 
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { ListPage } from '../pages/list/list';

import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { HttpModule } from '@angular/http';
import { CategoryIdToName } from '../pipes/category-id-to-name/category-id-to-name';

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    ListPage,
    CategoryIdToName
  ],
  imports: [
    BrowserModule,
    HttpModule,
    IonicModule.forRoot(MyApp),
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    ListPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

there is also a pipe in the tutorial but it isn’t being run yet, i really need the listing-category ID to show before i run the pipe to convert to name.

I’m aware i’ve posted a lot of info, but i’m still learning. Thanks for your help !


#4

the html you posted has nothing to do with the category. What does your console.log give?


#5

I’m not sure what you mean about the html ?

My console doesn’t seem to show anything of relevance, but it does seem to output any array of the listing-category.


#6

now I understand why you are getting null. I have just checked the json response. Its “listing-category”: [29].

So that particular code <h3>{{item.listing-category | json }}</h3> wont work as you are dealing with arrays/ Please see if below code work

<h3>{{item.listing-category[0]}}</h3>

Ashley


#7

I am not a big fan of innerHTML in the first place, but if you’re going to use it, be aware of its limitations. Only bare-bones elements like <b> are going to work - links and directives won’t.

I am also on a crusade against abuse of any. Get rid of all of your any and replace them with actual types.

Finally, initialize any arrays you are looping over: items = [].


#8

I tried that Ashley but unfortunately it gives me “undefined is not an object (evaluating ‘co.category’)”

The strange thing is that in the original tutorial for standard Wordpress Posts & Categories, if i present it as

{{item.categories | json }}

and obviously change my URLS to /post /categories it works as it should, strangely listing-category & categories are both structured in the same way to the best of my knowledge.

Also if i simply change

{{item.listing-category | json }}

to

{{item.location | json }}

the location ID is presented and again i believe location & listing-category are both structured the same way.

I’m confused lol


#9

Hi apropos, i appreciate your direction on the correct way to do things but currently i’m just trying to modify a tutorial to work with a different post type, i’m at very early stages of my development and this in itself is just an exercise to learn, with absolutely no intentions of it ever being used in the real world.

Most of the tutorials i have read seem to use innerHTML for some reason but i will certainly take on board what you said.

With regards to any and looping, i unfortunately haven’t got that far to even understand what that means, but no doubt that will be the next thing i read into.

Thanks for your input !


#10

This sounds to me like you stopped reading my post partway through. The very end of it should be the answer to your problem.


#11

No i absolutely read it to the very end … But i have absolutely no idea what it means … Apologies but i have literally just started learning this.


#12

TL;DR: You have items: any;. Change that to items = [];.

Longer explanation:

When you use *ngFor="let foo of foos" in a template, you are telling your controller (the TypeScript file) “I need your foos property to always be an array. Not ‘maybe at some point if we get a response from WordPress’. ALWAYS.”.

The template is trying to loop across items before it is actually an array, so you get an error. The easiest way to prevent this is to explicitly initialize any arrays in your controllers to []: an empty array that is still an array.


#13

Ok thanks for the explanation, i’m not going to pretend to fully understand it but i partially understand what you mean.

So having changed item: any; to items = [ ]; everything still works as it was but i’m still receiving null on listing-category

The bit that confuses me most is that if i use item.location it will display [39] as it should, which i believe is also an array or is certainly structured exactly the same as listing-category and infant is structured the same as standard wordpress categories, which work perfectly in the exact same setup.


#14

listing-category isn’t a valid JavaScript identifier, so you can’t use dot notation and must access it via object syntax instead: item['listing-category'].


#15

Bingo !! It now works as should. Thank you so much for your help.

Can i ask … Is that simply because it’s hyphenated ?


#16

Yes. Only alphanumeric, _ and $ are legal in identifiers.


#17

Thank you so much for pointing that out, i couldn’t understand why it worked for everything else and not that. I really appreciate your help and i will certainly read more into everything else you advised me on.

Thanks again !