How to call an external API


#1

Hi, still working my way around the adonis framework, I have a noob question:
I want to call the API of an external application (monday.com) and use the response (JSON) to display on one of my pages.

  1. How do I call the API from adonis? I know there are several packages (https, request, axios etc) but what is the best way forward?
  2. The data that comes back only needs some sorting, filtering etc before displaying. Where should the data live; can i simply add this to the context object? or is there a better way?

Hope my questions are clear and someone can help.
Boudewijn


#2

1 - There’s no information in the Official docs about this, so, i assumed that i would need an external package. Then, i created a “Service” Controller for this, the other Controllers call this “External API” controller.

2- If you want, you can save the data in some database table. But if you just need to “order”, pass it to the Controller.

I’m not an expert in Adonisjs but, i’m with a production API working for almost 2 months and I have come across many of these scenarios. That’s how i solved them.

Unversed


#3

Thanks. I tried axios and can get the data out of monday.com. I now did it in the js-file that implements Vue on my page, however that file loads and is visible in the “network” tab in developer console, and so would my Api Key be. So I would probably indeed need to go with the controller; any suggestion on how to do that? I want to use something like this:

loadDash: function(){
axios.get(‘https://api.monday.com:443/v1/users.json?api_key=myApiKey’)
.then((user_response) => {
userdata = user_response.data
console.log(this.userdata)
})
.catch((error) => {
console.log(error);
});
}

How do I pass the userdata from the controller to the view? or is that always available?


#4

Oh I found how to do it from the controller. Wasn’t that hard after all, just pass in the new acquired object to the view as an argument. Now will have to figure out how to get that into the vue file so I can process…


#5

Since your main concern is to proctect the credentials, I suggest creating a route on your server that calls that external API and returns JSON. Then hit this route from your vue app via axios


#6

Hi Virk, thank you for your response. I did it the other way around; called the controler function from the route, there I did the API call, and served the data coming from the call into the render function like so:

return view.render(‘dashboard’, {data: data})

not sure how my solution would be more unsafe or better, however if I understand your approach correctly, I have to:

  1. have a route ‘dashboard’ that renders the view with Vue js file linked
  2. from the Vue js file, request the data from the controller through 2nd route.get(‘dash’, ‘DashController.loadFromVue’) and use the promise with the data in my Vue js file;

That works, I can console the data however my view doesn’t render the data; the dom doesn’t contain them. I suspect this has to do with Vue more than with Adonis however I’m stuck here a bit. I tried both the ‘created’ and ‘mounted’ Vue functions but neither work.

Hope my question here is clear … :slight_smile:


#7

Hey @boudewijnt! :wave:

Before giving you any answer, I need to have more information.

  1. Are you building a Single-Page-Application with Vue?
  2. Are you building a Universal Application with Vue?
  3. Are you building a Server-Side-Rendered application with Adonis that use Vue to add UX to the frontend?

If I read correctly, it should be the third option, but I want to be sure. :smile:

If that’s the case, hydrating your Vue Instance with data you get from Adonis is perfectly fine.


#8

Hi Romain,

Thank you; yes I was working on option 3 indeed. So how do I get the data correctly into my Vue instance? I now did this to request the data from the api inside my vue app, which actually gets the data (can see in console and Vue-devtool):
mounted: function () {
axios.get(‘dash’).then((response) => {
this.userdata = response.data.users
this.boarddata = response.data.boards
this.loaded = true
})
}

However, on rendering, my edge file won’t recognize the data yet. Seems like it is rendered before the data is loaded into the Vue instance… What should I do here?
Boudewijn


#9

I see two ways of doing it.

  1. You fetch the data from Adonis and use Edge to hydrate your view instance.
  2. You fetch the data from Vue in the created lifecycle hook and hydrate your model afterward.

I can give you a code example if you tell me which way you prefer.


#10

Hi Romain, I think I would prefer option 2, since I then have all the data in my Vue instance. I can then get the user to make selections with eg checkboxes which simply selects and filters data.
Much appreciated!


#11

To clarify, in both case VueJS would have the data in its state and you will be able to select and filter data.

The difference between the two is how VueJS got the data.

  1. You fetch the data in Adonis and send them back as a props (via Edge)
  2. Your Vue instance start empty and fetch itself the data via AJAX afterward

#12

Hi Romain, yes I think I understand both ways, however:

  1. In this method I don’t know how to access the data from the VueJS instance; I send the data from the controler to the view, but how to access the data object in Vue?
  2. I succeeded to load the data through an AJAX request (with Axios) in the ‘created’-hook but then the template does render with ‘undefined’ properties; seems it loads before the data is available or so.

If both work I’d appreciate an example of any one you’d prefer, I expect I am super close to the solution but miss 1 small bit to complete here…

Realy appreciate the work you guys do here, also in support.