I've read through numerous answers on SO, but most don't show both the Flask and JS side of my question, so I don't believe this is a duplicate. Specifically, using React/JS, I'm attempting to fetch a list of dictionaries from my Flask API.
On the server side, I've successfully serialized my class, and can print the list of dictionaries as expected. However, after I return it using JSONIFY (as suggested in several SO questions), it results in undefined on the JS side when I try to access the data. From reading online, it appeared that I could attempt to JSON parse the response data, but this similarly shows undefined. This leads me to believe that the issue may in fact be on the server side. Regardless, I'm also unsure how to properly access this list of dictionaries in my fetch function (I would've expected that I can do something along the lines of data[0]['name']).
I'd really appreciate any guidance you might have - thank you for reading this far.
eqtls prints as follows in api.py:
[{'id': 1, 'name': 'Bearbrook Skateboard Park', 'description': 'Flat asphalt surface, 5 components', 'xcoord': -75, 'ycoord': 45, 'date_added': datetime.datetime(2021, 10, 26, 19, 46, 10)}]
api.py
class Activity(db.Model):
id = db.Column(db.Integer, primary_key=True)
xcoord = db.Column(db.Integer,nullable=False)
ycoord = db.Column(db.Integer, nullable=False)
name = db.Column(db.String(200))
description = db.Column(db.String(200))
date_added = db.Column(db.DateTime, default = datetime.utcnow)
#create a string
def __repr__(self):
return f"<id={self.id}, name={self.name},description={self.description},xcoord={self.xcoord},ycoord={self.ycoord},date_added={self.date_added}>"
def serialize(self):
return {
'id': self.id,
'name': self.name,
'description': self.description,
'xcoord': self.xcoord,
'ycoord': self.ycoord,
'date_added': self.date_added
}
#app.route('/allActivities', methods=['GET'])
def allActivities():
print('hit allActivities routing')
allActivities = Activity.query.all()
print(str(allActivities))
eqtls=[activity.serialize() for activity in allActivities]
print(str(eqtls))
sys.stdout.flush()
return jsonify(eqtls)
Currently in app.js, my data variable logs as undefined.
app.js
useEffect(()=> {
fetch('/allActivities').then(response => {
if(response.ok){
console.log(response)
return response.json()
}
}).then(data => setAllActivities(data))
.then(data => {
console.log(data);
//var jsonData = JSON.parse((data));
//console.log(jsonData[0].name);
})
},[])
Related
I'm working on the front-end of an API in react and I'm trying to get the ten first items of a JSON list like:
[{"element1":"value", "element2":"value"}, {"element1":"other value", "element2":"other value"}, ...]
But I don't know how to do that with Axios :/
I found nothing in the Axios' Docs or on this forum
Thanks for your help :)
What you are talking about is called pagination and this feature should be implemented on the back end. If pagination is not supported by the backend, then you just have to use regular js array methods, for example, slice https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
Ok, so what you are going to want to use is headers with Axios. Like this:
// headers are like variables that tell your backend what it needs to know
const config = {
headers: {
numberOfElements: 5
}
}
axios.get('/apiendpoint', config)
.then((response) => {
// what your backend is sending the frontend
console.log(response);
})
Then in your backend you can get the data from that header with express and serve your data:
const express = require('express');
const app = express();
// here is your example data
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
app.get('/urlendpoint', (req, res) => {
// use the req.get method to get the header data
const numberOfElements = req.get('numberOfElements');
// now we can use the arrays .slice() method to get the first x elements of an array and send it in the response
res.send(numbers.slice(0, numberOfElements));
});
you can read more about the .slice method here
I m trying to get an array from react frontend (stored in local storage) to my view class in django but i'm getting this error:
In console:
GET http://127.0.0.1:8000/api/quiz/multiple/ 500 (Internal Server Error)
Django LOGS:
for quiz in quizzes:
TypeError: 'NoneType' object is not iterable
ERROR:django.server:"GET /api/quiz/multiple/ HTTP/1.1" 500 20064
Here's how i store the data in the LocalStorage:
localStorage.setItem('quizzes', JSON.stringify(quizList));
history.push('/start')
And here's how i get it from local storage and pass it to the django using axios:
export default function QuizPage() {
const [DataState,setDataState] = useState([]);
const storedQuizzes = JSON.parse(localStorage.getItem("quizzes"))
useEffect(() => {
axiosInstance
.get(`quiz/multiple/`, {
quizzes: storedQuizzes
}).then((res) => {
setDataState(res.data);
})
.catch((function (error) {
console.log(error)
}));
}, [setDataState]);
and, finally, that's my django view:
class MultipleQuizView(APIView):
permission_classes = [IsAuthenticated]
def get(self,request):
questionsList = []
quizzes = request.data.get('quizzes')
for quiz in quizzes:
currentQuiz = Quiz.objects.get(url=quiz)
quizSerializer = QuizSerializerForMultipleQuizzes(currentQuiz)
question = Question.objects.filter(quiz__url=quiz)
questionSerializer = QuestionSerializer(question, many=True)
quizSerializerData = quizSerializer.data.copy()
quizSerializerData["questions"]=questionSerializer.data
questionsList.append(quizSerializerData)
if questionsList:
return Response(questionsList)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
I'm pretty sure the problem isn't from my view class because i tested it using Postman and it works without any problem.
EDIT:
I just tryed with postman using this body and it works properly:
https://i.stack.imgur.com/3RJ5A.png
So i need to send data from react like this but i don't know how:
{
"quizzes":["securitate","aparare"]
}
Try changing the second param to axios.get as follows:
axiosInstance
.get(`quiz/multiple/`, {
params: {
quizzes: storedQuizzes
}
}).then(...)
Read more about the properties that the second param supports.
SOLVED!
The problem was that i wrote:
quizzes = request.data('quizzes')
instead of:
quizzes = request.data['quizzes']
I could use assistance understanding and fixing my error for the following:
Javascript calls the following function during some event on the page:
function load_homePage() {
// Pull all posts
fetch('/homepage')
.then(response => response.json())
.then(posts => {
// Print all posts
posts.forEach( function(post) {
console.log(post)
})
})
}
Eventually, I will have JS create dynamic Div's to display all the data that comes in from the call.
Fetch is calling to the following view:
#csrf_exempt
#login_required
def view_homePage(request):
posts = Post.objects.all()
# Return entire set of posts to webpage
return JsonResponse([post.serialize() for post in posts],
safe=False)
Here all I want is for Django to query the database, pull all the data from the Post model, and send it back to the page. The model is as follows:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class Post(models.Model):
posterID = models.ForeignKey("User", on_delete=models.CASCADE,
related_name="post")
content = models.TextField(blank=False)
timestamp = models.DateTimeField(auto_now_add=True)
def serialize(self):
return {
"id": self.id,
"posterID": self.posterID,
"content": self.content,
"timestamp": self.timestamp
}
The Url.py file is also complete:
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("post", views.new_post, name="posts"),
path("homepage", views.view_homePage, name="homepage")
]
When I try to get the event to fire I get the following error:
TypeError: Object of type User is not JSON serializable
[23/Sep/2020 02:51:09] "GET /homepage HTTP/1.1" 500 107660
Can someone advise me as to what I am doing incorrectly and how to do it correctly? Thank you for your time.
I figured out the answer and thought I would post it here in case it is of value to anyone. The issue is in the model code. Specifically here:
def serialize(self):
return {
"id": self.id,
--->"posterID": self.posterID,<----
"content": self.content,
"timestamp": self.timestamp
}
Being a foreign key to User, it was returning:
"posterID": User: someName
I fixed it by changing the offending line to:
"posterID": self.posterID.id,
im very new to Javascript, Django & web development in general. Im following a cs50 web dev course by harvard and I have to design a front-end for an email client that makes API calls to send and receive emails.
Ill get mail, send mail, and update emails by using an API that is written specifically for us.
I need to send a GET request to /emails/ where is either inbox, sent, or archive, and it will return back (in JSON form) a list of all emails in that mailbox, in reverse chronological order.
How to fetch, as instructed by the course:
fetch('/emails/sent')
.then(response => response.json())
.then(emails => {
// Print emails
console.log(emails);
// ... do something else with emails ...
});
I put this exact code in my .js file and it gives me these two errors:
GET http://127.0.0.1:8000/emails/sent 500 (Internal Server Error)
load_mailbox # inbox.js:85
(anonymous) # inbox.js:24
127.0.0.1/:1 Uncaught (in promise) SyntaxError: Unexpected token < in
JSON at position 0
Promise.then (async)
load_mailbox # inbox.js:87
(anonymous) # inbox.js:6
What shows at the cmd:
Is the issue at the timestamp of the model in django? I dont understand why.
Internal Server Error: /emails/sent
Traceback (most recent call last):
File "C:\Python\Python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python\Python38\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\AG\Desktop\cs50\mail\mail\views.py", line 96, in mailbox
return JsonResponse([email.serialize() for email in emails], safe=False)
File "C:\Users\AG\Desktop\cs50\mail\mail\views.py", line 96, in <listcomp>
return JsonResponse([email.serialize() for email in emails], safe=False)
File "C:\Users\AG\Desktop\cs50\mail\mail\models.py", line 26, in serialize
"timestamp": self.timestamp.strftime("%b %-d %Y, %-I:%M %p"),
ValueError: Invalid format string
Code given by the course:
models.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class Email(models.Model):
user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="emails")
sender = models.ForeignKey("User", on_delete=models.PROTECT, related_name="emails_sent")
recipients = models.ManyToManyField("User", related_name="emails_received")
subject = models.CharField(max_length=255)
body = models.TextField(blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
read = models.BooleanField(default=False)
archived = models.BooleanField(default=False)
def serialize(self):
return {
"id": self.id,
"sender": self.sender.email,
"recipients": [user.email for user in self.recipients.all()],
"subject": self.subject,
"body": self.body,
"timestamp": self.timestamp.strftime("%b %-d %Y, %-I:%M %p"),
"read": self.read,
"archived": self.archived
}
views.py, this function i believe it returns the emails from my request:
#login_required
def mailbox(request, mailbox):
# Filter emails returned based on mailbox
if mailbox == "inbox":
emails = Email.objects.filter(
user=request.user, recipients=request.user, archived=False
)
elif mailbox == "sent":
emails = Email.objects.filter(
user=request.user, sender=request.user
)
elif mailbox == "archive":
emails = Email.objects.filter(
user=request.user, recipients=request.user, archived=True
)
else:
return JsonResponse({"error": "Invalid mailbox."}, status=400)
# Return emails in reverse chronologial order
emails = emails.order_by("-timestamp").all()
return JsonResponse([email.serialize() for email in emails], safe=False)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
# API Routes
path("emails", views.compose, name="compose"),
path("emails/<int:email_id>", views.email, name="email"),
path("emails/<str:mailbox>", views.mailbox, name="mailbox"),
]
My.js code where i use fetch:
document.addEventListener('DOMContentLoaded', function () {
// Use buttons to toggle between views
document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
document.querySelector('#compose').addEventListener('click', compose_email);
//code..
});
function compose_email() {
//code..
}
function load_mailbox(mailbox) {
// Show the mailbox and hide other views
document.querySelector('#emails-view').style.display = 'block';
document.querySelector('#compose-view').style.display = 'none';
// Show the mailbox name
document.querySelector('#emails-view').innerHTML = `<h3>${mailbox.charAt(0).toUpperCase() + mailbox.slice(1)}</h3>`;
//problem:
//i will change the 'sent' string in the future
fetch('/emails/sent')
.then(response => response.json())
.then(emails => {
console.log(emails);
});
}
self.timestamp.strftime("%b %-d %Y, %-I:%M %p")
You are using Python 3, but the code you were given was written for Python 2 (or by someone who didn't know all the difference with Python 3 so you might expect other hurdles down the road). They are used for non zero-padded versions of d and I.
In Python 3, -d and -I do not make sense to the parsing engine, and I don't think there are non zero-padded versions.
You can safely remove the -.
In Django, I want to render a page that includes a Chart js chart that relies on data from my database. I believe I need to implement an API for this. The same page with the chart will contain other info from the database that I think is rendered with a context dictionary and {{ variable }}. I know how to do one or the the other, but not both on the same page. Here is what I have so far. In views.py:
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.views import generic
from django.views.generic import View
from .models import Article
from rest_framework.views import APIView
from rest_framework.response import Response
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
articles = Article.objects.all()
correlationlist = []
nocorrelationlist = []
for corr in articles:
if corr.correlation_type == "Correlation":
correlationlist.append(1)
nocorrelationlist.append(0)
elif corr.correlation_type == "No Correlation":
correlationlist.append(0)
nocorrelationlist.append(1)
else:
pass
correlation_items = correlationlist
nocorrelation_items = nocorrelationlist
data = {
"correlation_items": correlation_items,
"nocorrelation_items": nocorrelation_items,
}
return Response(data)
The Javascript I have on the page where the chart appears is:
$(document).ready(function(){
var endpoint = 'api/chart/data/'
var defaultData1 = []
var defaultData2 = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultData1 = data.correlation_items
defaultData2 = data.nocorrelation_items
setChart()
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
function setChart(){
CHART js code goes here
}
})
But on the page where the chart appears, I also want to include other information from the data base, such as:
The title of the article is: {{ title }}
To do this and to render the page, I think I need to create a function in views as follows:
def results(request):
myresults = Article.objects.all()
context = {'myresults': myresults}
return render(request, 'my_page_with_results_and_chart.html', context)
In short, how do you render a page that pulls data from an API for a chart, but also gets database information from the render(request, 'page.html', context) method? This is driving me crazy.
not really sure what you're asking, seems very ambiguous. From a glance it looks like, myresults = Article.objects.all() and articles = Article.objects.all() are the same and you just want to get the title from the article?
Just add articles into your data dictionary
data = {
"myresults": articles,
"correlation_items": correlation_items,
"nocorrelation_items": nocorrelation_items,
}
then just reference it in your html. You cant just do {{ title }} though like your example as 'title' is not a key to your dictionary. if 'articles' is a dictionary with title as a key, you'll need to do {{ myresults.title }} in the html. I hope i answered your question :/
I'm not sure if this is what you're asking as it seems too basic but just from your examples it looks like you are..? Anyway if you do need to make an api the Django RESTful library is really good and great documentation http://www.django-rest-framework.org/