• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Populating React dropdown list with data from axios request

 
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Inside of my main `App.js componentDidMount()` lifecycle phase I have an axios get request to a rest service.

   

This request is successful in returning an array of schemas(strings) (only 1 for now) in the console messages



How can I populate this `UserForm.js` dropdown list with the `Phone Record` that was returned by the axios get request

   
 
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is schema a property or a state of the form? You have it as if it is both. Hint: it's a property, why is it a state of the form?

 
Bear Bibeault
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And on line 30, what does schemas refer to? Where has it been defined?
 
Dj Marlins
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:And on line 30, what does schemas refer to? Where has it been defined?



Should the state of form be data instead? On line 30, I am checking to make sure that API call is not returning an empty schema array.
 
Bear Bibeault
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dj Marlins wrote:Should the state of form be data instead?


The question was: why are you declaring schemas as part of the form component state? Where is it supposed to get the list of schemas that is returned by the Ajax request?

On line 30, I am checking to make sure that API call is not returning an empty schema array.


You evaded the question. Where is schemas defined in that scope?
 
Bear Bibeault
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
P.S. Why I am poking at these questions: understanding how to use props and state properly is fundamental to using React effectively.
 
Dj Marlins
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:
The question was: why are you declaring schemas as part of the form component state? Where is it supposed to get the list of schemas that is returned by the Ajax request?

You evaded the question. Where is schemas defined in that scope?



It can't get the list that is returned, that's where I'm stuck. The list is rendered inside my main app, how can I manipulate that data inside my form component
 
Dj Marlins
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:P.S. Why I am poking at these questions: understanding how to use props and state properly is fundamental to using React effectively.



Would I be better served to make the api call from inside the userform component?
 
Bear Bibeault
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, clearly you are missing some React and JS fundamentals. Let's fix that...

You are getting the list of data (of what? phone records? something else? I'll assume "schemas") back from an Ajax call made in the App component. You set the whole response into the App state as schemas. Why set the whole response, including HTTP status into the state rather than just the data member? Is there any reason to carry around HTTP information? Usually not.

You want to pass that data down into the form component and you do so on line 32 by passing the whole response as a prop named schemas. That's misleading as it is not the list of schemas but the whole response. Again, why the whole response? If there's a good reason for that, you should use a different prop name that indicates that. But all that HTTP data isn't really needed, is it?

So from here, I'll assume that you are going to fix that and only pass the list of schemas.

Then things really go off the rails. You pass the list to the form component and then never reference it again.

In the UserForm component, you create another (empty) list called schemas in the state. Why? You are passing the list as a prop (at least once you fix the problem of passing the whole response) so it's not needed in state. You should only put things into state that you don't have in props, or that you need to manipulate within the scope of the component. As I understand it, you will be using the list to populate a control, so there is no need to have the list in state.

On line 30, you reference the name schemas yet it has been declared nowhere in that scope. So what happens when you reference a name that hasn't been defined? Answer: it assumes it is a global name and so is looking in window.schemas, which of course does not exist.

You want to reference the list of schemas that was passed as a prop, so the correct reference is this.props.schemas.

You could just use that reference three time on line 30, but that makes the code unwieldy and less clear, so convention dictates that you should pull it out of props into a simpler name, So:So now the name schemas references the list you got back in the response and passed as a prop. Note the use of const and deconstruction syntax. If this is new to you, bone up on it quickly; it's used everywhere in React.

But then on line 31 you reference a single element of the list using property names of value and name, which don't match the sample data you got back from there request at all, assuming that the sample data you posted is the actual shape of the data. In that example, the single element that was returned is the string "Phone Record", not any kind of data that has value and name properties. So what's incorrect: the returned data shape? or the references?

So a summary of some major problems I see in the code:
  • The response is being saved in its entirety in App state which you pass down as a property to the form. That reveals HTTP-specific details to lower levels which is not a proper level of abstraction. If all the child compnent(s) need is the list, just pass the list.
  • Creating a new list in the form component's state is clearly unnecessary.
  • You aren't referencing the prop containing the data list properly.
  • The actual data in the list does not match the shape that you assume in the form code.

  • Some other issues:
  • Why is the select element not its own component? You've got it tightly coupled to the form here. What if it needs to be used again elsewhere? Even if it doesn't need to be reusable, it should be abstracted into its own component.
  • You pull in the PropTypes module but never declare the prop types.
  • And wonky indentation. This is a silent killer because many people don't think that it's all that important. They are wrong. Why is line 4 of App not indented within the body of the constructor? Why is line 12 indented at a different level than the constructor? Why is the import of UserFrom line 2 not at the same level as the import of line 1? Why is the class at line 4 at two levels of indent when it should be one? Pay attention to your indentation. It not only makes the code read easier, it's an important skill to master right from the start.


  • So let's see your new code that addresses the above problems. And I can't stress proper indentation enough. Without it, the structure of the code and components is garbled.
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    The following was posted while I was writing the above response

    Dj Marlins wrote:Would I be better served to make the api call from inside the userform component?



    Answer this: if you need to use this same select control in another form elsewhere in the application, how does that affect your thinking about asking this question?
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote:OK, clearly you are missing some React and JS fundamentals. Let's fix that...


    So a summary of some major problems I see in the code:

  • The response is being saved in its entirety in App state which you pass down as a property to the form. That reveals HTTP-specific details to lower levels which is not a proper level of abstraction. If all the child compnent(s) need is the list, just pass the list.
  • Creating a new list in the form component's state is clearly unnecessary.
  • You aren't referencing the prop containing the data list properly.
  • The actual data in the list does not match the shape that you assume in the form code.

  • Some other issues:
  • Why is the select element not its own component? You've got it tightly coupled to the form here. What if it needs to be used again elsewhere? Even if it doesn't need to be reusable, it should be abstracted into its own component.
  • You pull in the PropTypes module but never declare the prop types.
  • And wonky indentation. This is a silent killer because many people don't think that it's all that important. They are wrong. Why is line 4 of App not indented within the body of the constructor? Why is line 12 indented at a different level than the constructor? Why is the import of UserFrom line 2 not at the same level as the import of line 1? Why is the class at line 4 at two levels of indent when it should be one? Pay attention to your indentation. It not only makes the code read easier, it's an important skill to master right from the start.


  • So let's see your new code that addresses the above problems. And I can't stress proper indentation enough. Without it, the structure of the code and components is garbled.



    Firstly, I appreciate these pointers as they've helped me understand more about react. I have updated my UserForm to reflect most of your suggestions.



    Could you shed some insight on what is doing here?
    After digging through some karaf logs as well, it seems I'm running into a constraint violation in my DB, so that will require some more attention to see what the underlying issue is.
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    This is an example of the Phone Record that is returned by my rest service.
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:This is an example of the Phone Record that is returned by my rest service.



    XML???      
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:Could you shed some insight on what is doing here?



    See: https://reactjs.org/docs/forms.html. There is a section on select elements.

     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote:
    XML???      



    Yes it is XML, I'm seeing it would be easier if it was JSON instead.
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:

    Bear Bibeault wrote:
    XML???      



    Yes it is XML, I'm seeing it would be easier if it was JSON instead.



    This, however is logged in the console



     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    OK, so is an array of strings what you expect as a response?
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote:OK, so is an array of strings what you expect as a response?



    Yes. For some more detail, the React UI  makes a call to rest service 1, this service then calls rest service 2 where the xml representation is, unmarshal, marshal the payload and returns it to the React UI in the form of json array of strings.
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    If that's all you have that's all you can use to build your select dropdown.

    Another tip: avoid using bind() by defining handlers as arrow functions.
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote:If that's all you have that's all you can use to build your select dropdown.



    I still can't seem to get the first string of the array to populate the list
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You'll need to provide more details and your up-to-date code.
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote:You'll need to provide more details and your up-to-date code.



    There's been a few "minor" changes to URIs so that's reflected below and differs from the original post.



    This request is now returning data in a different shape than originally



    I didn't include it in the snippet but the services returns the same array but there are a few additional fields along with "name".



    So now, how can I return the field inside the . I'm thinking should do the trick. Or do I have to change the initial state of my App
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    value={schema.name}>{schema}</option>;


    As schema is now a data construct (with a name property), what do you expect {schema} to display?
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    As schema is now a data construct (with a name property), what do you expect {schema} to display?
    I'm not clear on what you mean.
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:I'm not clear on what you mean.



    You use {schema} as the body of the option element. What is it that you expect to appear there when schema is: {  "name": "Phone Record" }
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote: You use {schema} as the body of the option element. What is it that you expect to appear there when schema is: {  "name": "Phone Record" }



    I expect Phone Record to appear within the list selection
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:

    Bear Bibeault wrote: You use {schema} as the body of the option element. What is it that you expect to appear there when schema is: {  "name": "Phone Record" }



    I expect Phone Record to appear within the list selection



    Then the reference would need to be {schema.name}, no?
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote: Then the reference would need to be {schema.name}, no?



    I have tried this already and is not working.

     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:

    Bear Bibeault wrote: Then the reference would need to be {schema.name}, no?


    I have tried this already and is not working.


    Define "not working" and we've already established that the phrase {schema} is meaningless.
     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    P.S. The option element has no key attribute. What are you thinking that it does?
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote:P.S. The option element has no key attribute. What are you thinking that it does?



    It does not have a key attribute so it only needs the value element. ?

     
    Bear Bibeault
    Sheriff
    Posts: 67747
    173
    Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:?


    Correct. When the option is the selected option, the value of the value attribute is what will be submitted as the value of the control.

    If the content of the option and the value are the same, the value attribute can be omitted.
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Bear Bibeault wrote: If the content of the option and the value are the same, the value attribute can be omitted.



    Something still seems to be off as it's not populating the list with the schema name.
     
    Dj Marlins
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dj Marlins wrote:Something still seems to be off as it's not populating the list with the schema name.



    I have rectified the issue, and it is now working. Thank you for your help/suggestions throughout
    reply
      Bookmark Topic Watch Topic
    • New Topic