Passing an array from service/provider to page

I am trying to pass an array from service on to a page.

Service.ts

 public getAmount()  {
  this.storage.query("SELECT amount FROM budget").then(
      data => {
        this.amount = [];
        if (data.res.rows.length > 0) {
          for (var i = 0; i < data.res.rows.length; i++) {
            let item = data.res.rows.item(i);
            this.amount.push(Number(new item.amount));
          }
        }
      });
      return this.amount;
}

on the page i simple call for the service method as so:
page.ts

data: this.Service.getAmount();

this should be simple but for some reason it doesn’t work i get this error
EXCEPTION: Error: Uncaught (in promise): TypeError: item.amount is not a constructor

it appears that there are two problems first item.amount can’t add value to an array
and second array cant be pushed on to the page
any ideas??

this line should not contain the word “new” just write item.amount instead!

this.amount.push(item.amount);

Try that and let me know!

1 Like

thank you for the suggestion, it passed the array well sort of

no errors pop up but now i just have to figure out why is the array empty :confused:

because you’re in an async call when you query your storage. so this.amount exist for the time the query is executed.

 public getAmount()  {
  return this.storage.query("SELECT amount FROM budget");
}

then on the other side where you call your service this is where you’ll go through your array returned and fill up your array to display it to the UI.

this.service.getAmount().then(function(data) {
  this.amount = data;
});

something like that. Sorry my code is not explicit it’s been a while since i’ve played with typescript etc.

hope this helps!

1 Like

it did help a lot thanks ,
it did work to generate an array with the data from the db but the array is weird

placed in service.ts

public getAmount() {
return this.storage.query(“SELECT amount FROM budget”);
}

on page.ts

public passAvgWeek() {
    let amount = new Array();
    this.Service.getAvgWeek().then(
        data => {
          if (data.res.rows.length > 0) {
            for (var i = 0; i < data.res.rows.length; i++) {
              let item = data.res.rows.item(i);
              amount.push(Number(item.mount));
            }
          }
        });
        //amount = [5,9,6,5,4,7,6,4,7];
        return amount;
  }

to test i just call it to consol log

console.log(this.passAvgWeek());

and get this weird array it shows empty brackets and the correct data below

image

but then when i uncomment this test line - amount = [5,9,6,5,4,7,6,4,7];
i get a proper array
image

You’re trying to treat asynchronous code as if it were synchronous. Down that road lies nothing but pain. Don’t expect passAvgWeek to return actual data. It can’t and won’t, no matter what you try to do. It can return a Promise<Number[]> using the core of your then clause (which should be where amount is created and returned from, not outside of it). You cannot expect anything meaningful by logging what passAvgWeek itself returns, you need to do something like:

passAvgWeek().then((week) => {
  console.log(week);
});
1 Like

So what i am getting from your response is my current approach is no good, that much is obvious :slight_smile:

but i don’t understand the pseudo code you posted
could you elaborate a bit more on it

passAvgWeek(): Promise<Number[]> {
  return this.Service.getAvgWeek().then((data) => {
    let amount = [];
    // build amount from data
    return amount;
  });
}

passAvgWeek().then((week) => {
  // only in here can we access the actual "amount" array that was built in passAvgWeek()
});
2 Likes

much clearer thank you
but when i attempt to just build and
console log the the amount using the code

  private passAvgWeek(): Promise<Number[]> {
    return this.Service.getAvgWeek().then((data) => {
      let amount = [];
      if (data.res.rows.length > 0) {
        for (var i = 0; i < data.res.rows.length; i++) {
          let item = data.res.rows.item(i);
          amount.push(Number(item.amount));
        }
      }
      return amount;
    });
  }

it returns a bunch of syntax errors on this part, do i need to declare this "week’ somewhere

 line 52:     passAvgWeek().then((week) => {
                 // only in here can we access the actual "amount" array that was built in passAvgWeek()
                 console.log(amount);
                 });

‘{’ or ‘;’ expected.at line 52 col 16

I don’t know what the context is for your “line 52”, but a couple of things: since passAvgWeek is private, you’ll probably have to be calling it as this.passAvgWeek. Also, when you’re inside the “then” clause, “week” is going to be the array you returned as “amount”. It won’t be called “amount” any more at that point.

1 Like

changed passAvgWeek to public for simplicity
changed amount in console log to week but still the sintakse error just won’t let me build

Public or private, it’s an instance method that must be called via an object reference. There is no implicit “this” in JavaScript.

1 Like

with or with out this.

sintacs error persists

and wont build

Move passAvgWeek out of the page component and into the service (or modify getAvgWeek to include its logic). Declare a week property of type Number[] in the page component. Initialize it to an empty array immediately.

Then when you want to fill it, you do something like this in the page component:

this.service.passAvgWeek().then((week) => {
  console.log("got week " + week);
  this.week = week;
});

I don’t know when you want to do this: it could be called from someplace like ngOnInit or from a function invoked by a click event on a button or something. You can’t just randomly put it in the body of the page component class, though, like you are apparently trying to do now.

1 Like

that was it
THANK YOU !!! :smiley: :smiley: