Store string from JSON in a URL with typescript


#1

Hello,

I’m trying to create an array to store each post ID, here’s my .ts:

private url: string = "https://api.myjson.com/bins/1as3cr";
public ids: Array <any>;
public names: Array <any>;

constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams, public storage: Storage) {

  this.fetchContent();
}

  fetchContent ():void {
    let loading = this.loadingCtrl.create({
      content: 'Buscando categorias...'
    });

    loading.present();

    this.http.get(this.url).map(res => res.json())
      .subscribe(data => {
        this.ids = data.data;
        loading.dismiss();
        this.createCategories ();
      });
  }

  createCategories (){
    for (let entry in this.ids){
      alert (JSON.stringify(this.ids));
    }
  }

The alert is printing something like:

[{"term_id":3,"name":"Cultura","slug":"cultura","term_group":0,"term_taxonomy_id":3,"taxonomy":"category","description":"","parent":0,"count":1,"filter":"raw","cat_ID":3,"category_count":1,"category_description":"","cat_name":"Cultura","category_nicename":"cultura","category_parent":0},{"term_id":4,"name":"Política","slug":"politica","term_group":0,"term_taxonomy_id":4,"taxonomy":"category","description":"","parent":0,"count":2,"filter":"raw","cat_ID":4,"category_count":2,"category_description":"","cat_name":"Política","category_nicename":"politica","category_parent":0}]

What I’m trying to do is store only the “name”. I already tried this:

createCategories (){
  for (let entry in this.ids){
    alert (JSON.stringify(this.ids["name"]));
  }
}

But that returns: undefined.

How can I print, and store (later) the “name” attribute in this.ids?

Thank you!


#2

Create a variable before the loop, inside the loop only put the data you want inside the variable, after the loop you console.log the content of the variable to see if it worked.


#3

How’s that different from what I’m doing? I already created this variable on:

public names: Array <any>;

I’m not storing anything because I can’t get just the names but I already tried.


#4

You created a variable, but don’t use it for anything. So you are doing nothing.


#5

OK, this is what i tried:

createCategories (){

    for (let entry in this.ids){
      this.names.concat (this.ids["name"]);
      // alert (JSON.stringify(this.ids["name"]));
    }
    this.showCategories ();
  }

  showCategories (){
    for (let name in this.names){
      alert (name);
    }
  }

but I’m getting the error: undefined is not an object (evaluating 'this.names.concat')

How can I assign [“names”] to names (Array)?


#6

You don’t want to assign or concat, you want to push the name into the array.


#7

#8

Hey there, tried to chance and use push:

  createCategories (){
    for (let entry in this.ids){
      this.names.push (this.ids["name"]);
    }
    this.showCategories ();
  }

  showCategories (){
    for (let name in this.names){
      alert (name);
    }
  }

Now I’m getting: undefined is not an object (evaluating 'this.names.push')


#9

You need to initialize arrays before you push to them.
public names: Array<string> = [];


#10

It may sound silly, but investing the effort in giving properties meaningful and accurate names goes a long way towards making programs more readable. ids suggests that it is an array of identifiers. It isn’t. It seems to be an array of terms. As such, it should not be Array<any>, but rather Array<Term>, where Term is an interface that you define like so:

export interface Term {
  term_id: number;
  name: string;
  slug: string;
  // and so on
}

However, this is academic, because we’re going to make ids go away entirely.

This is not something that a page should be concerned with. You are saying that this page wants an array of names. Make a service provider that delivers one:

export class TermService {
  constructor(private _http: Http) {}
  // in case anybody wants the whole thing
  getAllTerms(): Observable<Term[]> {
    return this._http.get(url).map(rsp => rsp.json());
  }

  getAllNames(): Observable<string[]> {
    return this.getAllTerms().map(terms => terms.map(term => term.name));
  }
}

#11

That indeed solved the problem but for some reason, If I check if that element already exists the “FOR” breaks. For example:

 slug: string = '';
  public ids: Array <any>;
  public names: Array <any>;
  public names_string: string;

  constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams, public storage: Storage) {
    this.names = [];
    this.slug = '?categories=';
    this.names_string = '';
    this.fetchContent();
  }

  createCategories (){
    for (let entry in this.ids){
      if (this.names.indexOf (this.ids["name"]) > -1){
        //Do nothing, it's already there.
      } else {
        this.names.push (this.ids["name"]);
      }
    }
    alert (this.names);
    this.createSlug();
  }

  createSlug (){
    for (let name in this.names){
      this.slug.concat (name);
    }
    alert (this.slug);
  }

On alert (this.names); I get only the first element and alert (this.slug); I’m getting ?categories=. Why is that?


#12

Because concat doesn’t modify the string it’s called on; it returns a new one. Please get all of this junk out of the page component and into a service provider, though.