how to fetch the Data with JavaScript from my API?

My goal is to visualize my Model Data as charts or graphs. For the visualizing part I would like to choose Charts.js. So far I am able to display a chart in my template with a given default data. Now I would like to send my model data to my template and to integrate it in chart.js . Chart.js needs a JSON Format, as I understand. So I set up a API with the Django REST Framework and I got an Output.

Folder Structure

  visual # -- my project
    ├── cars # -- API
    │   ├── templates
    │   │   └── cars   
    │   │       └── cars_home.html
    │   ├── <...>
    │   ├── urls.py
    │   ├── serializers.py
    │   └── views.py
    ├── charts
    ├── static
    │   ├── css
    │   ├── img
    │   └── js
    │       ├── chart_2.js
    │       └── <...>
    ├── templates
    │   ├── base
    │   │   └── base.html
    │   └── includes
    ├── visual
    │   ├── settings.py
    │   ├── urls.py
    │   └── views.py   *db.sqlite3
    └── manage.py

../ cars / urls.py

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from cars import views
from cars.views import CarsHomeView

app_name = 'cars' 

urlpatterns = [
    path('carshome/', CarsHomeView.as_view(), name='cars_home'),
    path('cars/', views.SnippetList.as_view()),
    path('cars/<int:pk>/', views.SnippetDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

Here is the Output of my API:

http://127.0.0.1:8000/cars/

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 4,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 3,
            "name": "Audi",
            "price": 11
        },
        {
            "id": 4,
            "name": "Audi",
            "price": 11
        },
        {
            "id": 2,
            "name": "Mercedes",
            "price": 22
        },
        {
            "id": 1,
            "name": "BMW",
            "price": 99
        }
    ]
}

And this is the Raw-Output on

http://127.0.0.1:8000/cars/?format=json

{"count":4,"next":null,"previous":null,"results":[{"id":3,"name":"Audi","price":11},{"id":4,"name":"Audi","price":11},{"id":2,"name":"Mercedes","price":22},{"id":1,"name":"BMW","price":99}]}

The Question is how to fetch the Data with JavaScript from my API?

My Approach was, to first of all to simply print the data in my template, - to check if its works. Another thing is that try two different things. one is to put the JavaScript code in extern file in my static /js folder. This at least worked with the Chart.js and default values. But now i also provide the js code in my template, because maybe js has some issue to reference my api when it is in my static folder.

so here is the template.html. I have the JS fetch code from Tutorial Site, unfortunately i could not find a django - js example.

../ cars / templates / cars / cars_home.py

{% extends 'base.html' %}

{% load static %}

{% block content %}

<div class="container-fluid">
    <div class="row">
        <h1>Wellcome to Cars Home</h1>
    </div>

    <div class="row">


        <!--via external js-->
        <script src="{% static 'js/chart_2.js' %}"></script>


        <!--via internal js-->
        <script>
            fetch('http://127.0.0.1:8000/cars/?format=json')
                .then(response => {
                    return response.json()
                })
                .then(data => {
                    // Work with JSON data here
                    console.log(data)
                })
                .catch(err => {
                    // Do something for an error here
                })

        </script>

    </div>
</div>

{% endblock content %}

Another Question would be, do i need all this stuff in my API Output ?

{"count":4,"next":null,"previous":null,"

I guess it would be much nicer if it looks like this?

"results":[{"id":3,"name":"Audi","price":11},{"id":4,"name":"Audi","price":11},{"id":2,"name":"Mercedes","price":22},{"id":1,"name":"BMW","price":99}]}

Update: It seems my console in Firefox had some issues and did not display the Array and Objects. I changed to the Chrome Console and it showed me everything.

1 Answers

1
Caleb Davenport On Best Solutions

A few things

"count":4,"next":null,"previous":null," is what you'll want to paginate your API resources later. If you want to restrict your call to 10 at a time and show potential next pages on your website. If you showed 10 a page and there's a count of 25, you'd show 3 potential pages like an online shop. You'll probably need that later.

Is your script not doing anything? Are you not getting any data in the console? I would make sure you can go to that actual website in your browser and see something. I cannot access what's on your local machine.

<script>
            fetch('http://127.0.0.1:8000/cars/?format=json')
                .then(response => {
                    return response.json()
                })
                .then(data => {
                    // Work with JSON data here
                    console.log(data)
                })
                .catch(err => {
                    // Do something for an error here
                })

        </script>

I'd recommend looking into Jinja. It's a middleware designed to work with Django backends and let you directly use that data with html to do something like

{% for car in cars %}
  <li> <strong>{{car.name}}:</strong> {{car.price}} </li>
{% endfor %}