-1

So I created an SQL Database with a ton of information and a web service made in ASP.net Web API in order to make requests for data from the database. The client is a React-Native javascript app. I'm having issues trying to just isolate my JSON that I want from this weird Promise object. Yes, I feel like I'm missing the point of a Promise, but I just want to extract my data. Here's some code:

import RestClient from 'react-native-rest-client';

class FetchData extends RestClient
{
  constructor()
  {
    super('https://electionswebservice.conveyor.cloud/Api')

  }

  getOffices()
  {
    return this.GET('/Offices');
  }

  getSpecificOffice(id)
  {
    return this.GET('/Offices/' + id.toString())
  }

}

export default FetchData;

If called, getOffices() returns: https://i.stack.imgur.com/rfwW1.png

Sweet, all my data that I do want is in the _55 attribute of this Promise object. Based on all my searches, here's the closest I've been able to isolate what I need:

this.api = new FetchData();

this.api.getOffices().then(console.log);

This will return: https://i.stack.imgur.com/PQiAr.png

I haven't been able to return that array that I've been wanting. I want the array to get stored into a variable that I make in the SAME SCOPE :

this.api = new FetchData();

this.offices = this.api.getOffices()...;

How can I do that? (It's probably really obvious I'm probably having some kind of brainfart)

  • 1
    If `getOffices` resolves to an array, did you try `this.api.getOffices().then(arr => arr.forEach(elm => /* do something with each element in array */ ))` ? – CertainPerformance May 03 '18 at 00:48
  • @CertainPerformance getOffices resolves to a Promise object, see https://i.imgur.com/RgebZVd.png. – Marcus Orciuch May 03 '18 at 01:08
  • I mean, when the promise resolves - if the promise resolves to an array, then you should be able to use the array, right? – CertainPerformance May 03 '18 at 01:08
  • @CertainPerformance Just tried what you said originally, console logging each element works, however I want to store all these entries into an array outside of the then clause in a variable I declared earlier. So I tried adding each element to an array but the function contained in the forEach shows this: https://i.imgur.com/fBZttGP.png. New array is not touched. – Marcus Orciuch May 03 '18 at 01:18
  • It's sounding like you want to return the response from an asynchronous call..? – CertainPerformance May 03 '18 at 01:27
  • @CertainPerformance Yeah, is that wrong? I'm sorry I don't really know the etiquette of this kind of stuff. – Marcus Orciuch May 03 '18 at 01:30
  • In short, have the other part of the code (that needs the array) consume the promise returned by `getOffices` – CertainPerformance May 03 '18 at 01:32
  • This will help. http://andyshora.com/promises-angularjs-explained-as-cartoon.html – Sean May 03 '18 at 02:43

2 Answers2

0

It should be simple, just assign your variable inside the promise then() block, like:

this.api.getOffices().then(function(offices) {
  this.offices = offices;
});

Just be aware that the code below this block will not have access to the this.offices value, that is, subsequent code that uses this value should also be within your then() block, or you will need to refactor it a little bit (using async/await) or getting a better grasp of how promises work.

Guilherme Lemmi
  • 3,271
  • 7
  • 30
  • 30
  • Why is it that I cannot use that data outside of the .then block? When I assign `this.offices = offices;` , does the data just self destruct after completing the then block? – Marcus Orciuch May 03 '18 at 01:28
  • The problem is that the then() block is asynchronous and at the moment you try to use this.offices outside of then() it is not garanteed that it has been assigned yet, so you get undefined, or whatever it was before calling your api. – Guilherme Lemmi May 03 '18 at 01:33
  • Something you could do is to isolate this code in a separated function 1) `function getOfficesAsync() { return this.api.getOffices().then(function(offices) { return offices;});}`, and use it when you need the list of offices: 2) `getOfficesAsync().then(function(offices) { //do something you need with your offices });`. This function (1) could also store the value somewhere (local/session storage,some cache) once it gets for the first time, so that you don't need to call the api everytime you need the value. But the best would be to take a look at async/await, it is really the way to go. – Guilherme Lemmi May 03 '18 at 01:40
0

In React-Native, you usually update the state of a component when the API call returns. To do this you use the setState() function of the component. For example:

this.api.getOffices().then(
   (officesData) => {
     this.setState({ offices: officesData })
   }
);

The call to setState() will update the component and render it with the new offices data received. For example, the following will display the length of the array received.

render() {
   return ( 
      <View> 
         <Text> {this.state.offices.length} </Text> 
      </View>
    )
}

Make sure you initialize this.state.offices with an empty array in the constructor of the component.

Phil C
  • 431
  • 4
  • 7
  • This still doesn't work. The state variable that I assign the new data with is undefined outside of the `.then` statement. – Marcus Orciuch May 03 '18 at 23:14
  • My bad, the then() statement needs an arrow function instead of a classic function. Classic functions redeclare the this object and do not work in this context unless you bind then. – Phil C May 05 '18 at 12:42