Django, Javascript: passing data disables functions inside app - javascript

I'm aware that a lot of people asked a similiar question, but none of these helped me with my problem!? Inside my view I'm passing the name of the active user...
views.py
def index(request):
user = User.objects.get(username=request.user)
user_name = f"{user.first_name} {user.last_name}"
json_data = json.dumps(user_name)
return render(request, 'index.html', {"user_name": json_data})
script.js
let user_name = {{user_name|safe}};
But when trying to attach the data to my variable inside javascript, I'm getting the following error and all of my other functions inside js stop working!
SyntaxError: Unexpected token '{'
Does someone know what I'm doing wrong here?
Thanks for your help and have a great day!

Okay...dunno if this is a propper solution for my problem, but at least now it's working as it should! I'm passing the data into my index.html, so that I'm able to access it further down the line inside my script.js!
index.html
<script>
let username = {{ user_name|safe }};
</script>
<script type="text/javascript" src="{% static '...' %}"></script>

Related

Passing a Dictionary from Django view to a Django template

I am trying to pass the following context from views.py to a Django Template:
views.py:
def home(request):
context = {
'dict_1': {'key_1': ['val_11', 'val_12'], 'key_2': ['val_21', 'val_22']}
}
return render(request, 'app/home.html', context)
home.html:
<script type="text/javascript">
var java_dict = {{ dict_1 }};
console.log(java_dict);
</script>
This throws an error: Uncaught SyntaxError: Unexpected token '&'
Upon investigating, I see that the dictionary in javascript is read as follows:
{'key_1': ['val_11', 'val_12'], 'key_2': ['val_21', 'val_22']}
which probably means that the quotes-character (') is read incorrectly. How do I fix this issue?
The context data that you pass into Django templates are escaped by default, for security purposes.
If you're sure that the data is safe, you can do this:
views.py
import json
def home(request):
# Use JSON dump so that it will be a data that can be loaded in javascript
context = {
'dict_1': json.dumps({
'key_1': ['val_11', 'val_12'], 'key_2': ['val_21', 'val_22']
})
}
return render(request, 'app/home.html', context)
home.html
<script type="text/javascript">
var java_dict = {{ dict_1| safe }}; // Actually solve your problem. Don't escape the data.
console.log(java_dict);
</script>
By default, all values in Django templates escape HTML characters for security purposes. If you want to use this dictionary in JavaScript you should use json_script filter. Please read the docs to understand what's going on.
A solution for your problem would be to:
Add the script tag containing your dict to the template
{{ dict_1 |json_script:"ID_OF_NEW_SCRIPT_TAG" }}
Load the dict value in your script tag (I'll use the name you had in your example)
var java_dict = JSON.parse(document.getElementById('ID_OF_NEW_SCRIPT_TAG').textContent);
console.log(java_dict);
Replace ID_OF_NEW_SCRIPT_TAG with whatever ID makes sense to you.

How to import data from django.models, to use in javascript?

I am trying to import a python dictionary from moodels and manipulate/print it's properties in Javascript. However nothing seems to print out and I don't receive any error warnings.
Views.py
from chesssite.models import Chess_board
import json
def chess(request):
board = Chess_board()
data = json.dumps(board.rep)
return render(request, 'home.html', {'board': data})
Here board.rep is a python dictionary {"0a":0, "0b":0, "0c":"K0"} - basically a chess board
home.html
<html>
<body>
{% block content %}
<script>
for (x in {{board}}) {
document.write(x)
}
</script>
{% endblock %}
</body>
</html>
I also would very much appreciate some debugging tips!
Thanks in advance, Alex
Django defaults to escaping things as HTML, and that will make " into #quot;. Try changing {{board}} into {{board|safe}} to prevent the html escaping. Alternatively, in the view you can wrap the string in mark_safe() which is in django.utils.safestring to indicate that the string shouldn't be escaped.
To transfer data between django and javascript, dump data in django view and load in a javascript variable. Try to avoid django interpolation with javascript language constructs. It is unsafe, error prone, and can cause complexities.
in view
data = json.dumps(board.rep)
in template
const data = JSON.parse('{{ data|safe }}')
// use normal javascript here. 'data' is a javascript array
for (let x of data) {
document.write(x)
}

FOR loop over a Django model in a JS script

I just started a web app using Django and HTML/Javascript templates.
My Django spot app contains a Spot model that is sent to a HTML template - to be used with the Google Map Api. I've encountered a problem when looping over the variable spots containing Spot.objects.all().
It seems the problem comes from the way I send the data to the HMTL file.
----------------------------------------- Spot Django-app : models.py --------------------------------------------
class Spot(models.Model):
idn = models.IntegerField(unique = True)
name = models.CharField(max_length = 200)
longitude = models.FloatField()
latitude = models.FloatField()
------------------------------------------------- HTML / JS -----------------------------------------------
<script type="text/javascript">
var IDs = []
var names = []
var lat = []
var lng = []
{ % for spot in spots % }
IDS.push( {{spot.idn}} );
names.push( {{spot.name}} );
lat.push( {{spot.latitude}} );
lng.push( {{spot.longitude}} );
{ % endfor % }
Then, the lists do not contain any data that can be used afterwards. Worse, the HTML file does not work if the names.push( {{spot.name}} ) is un-commented.
----------------------------------------- Spot Django-app : views.py --------------------------------------------
from spots.models import Spot
def index(request):
return render(request, 'index.html', {'spots':Spot.objects.all()})
Thanks to the other stackoverflow questions (listed below), I also tried to serialize the Spot.objects.all() either with django.core.serializers.serialize("json", Spot.objects.all() ) or by creating my own serializer (thanks to Django_REST). The problem remains the same. So is the problem in the way I parse my data with JS?
I've look the following link :
Returning JSON array from a Django view to a template
django for loop in a .html template page (newbie)
Django FOR LOOP in JavaScript
with no success. So if the answer is included or related to these topics, would you mind explaining me something I've been working around for days ...
EDIT:
The problem was plural:
Serializing the data (or not ; I did not for now but everyone who answered agreed to say that it's better to)
Adding the quotes from {{ spot.name }} to '{{ spot.name }}', only to non Integer/Float models (i.e. only the models.CharFields fields)
Google Maps Api may return errors for some (longitude, latitude) tuples even if they are well-defined
Django will not recognize those template tags because you have spaces between the brace and the percent. So, there is no looping being done at all. You need to write them in the correct format:
{% for spot in spots %}
...
{% endfor %}
Once you do that, you'll start getting all sorts of JS syntax errors because you have not wrapped any of your data in quotes. But, as the comments say, doing this as JSON would be much better.
Even that I think that serializing your data into Json is much better idea. Your javascript code does not work because e.g. {{ spot.name }} will render raw string so for javascript to understand it you need to put it in quotes (and of course semicolon after each line).
names.push('{{spot.name}}');

get current user in Javascript/jQuery Laravel 5.1

How I can get the current user in JS/Jquery? In the blade we can do like
{{Auth::user()}} But it wont work in the .js file.
As per looking at the standard and the way most javascript templates engine work, I would prefer to do something like this:
Install laracasts/utilities by using composer require laracasts/utilities
In the controller method, from where you are returning view, I would make it look like this:
public function returnUser(){
$user = Auth::user();
Javascript::put([ 'user.name' => $user->name, 'email' => $user->email ]);
return view('my.user.js');
}
In the blade file, I would simply do,
<script>alert("Hi " + user.name + ". Your email is " + user.email)</script>
And yeah, I would even prefer the way, #Robbin said. And yeah just one more edit to his answer, in laravel 5.1, Auth::user() should not be used. It should be used as auth()->user() //->name or ->email or ->anything.
You have to build an API and get it with AJAX. You cannot use blade in javascript files.
Or, in the <head> of your template, you place.
<script>
var user = {!! json_encode((array)auth()->user()) !!};
</script>
<!-- include your js file here-->
And use the user var in your js file.
EDIT:
As per Mark's comment this is indeed cleaner:
<script>
var user = {!! auth()->user()->toJson() !!};
</script>
<!-- include your js file here-->
simply =>
add any input or any tag to inject auth-user inside it, in my case:
< meta name="auth-check" content="{{ (Auth::check()) ? 'true' : 'false' }}">
in JS file u can get a value from your tag using jquery!
var authcheck = $('meta[name="auth-check"]').attr('content');
I hope my idea is useful, my best wishes

Using last.fm API in javascript

I have very little experience with web development. I have a little experience with HTML and I am learning JavaScript right now. I created a program in Java using a a last.fm library for Java. I was able to get user information, artist information, and venue information. Now I want to try and do that in a webpage, which is where my problem occurs.
I'm using the javascript last.fm api given here http://github.com/fxb/javascript-last.fm-api
I've downloaded all the .js files and they are in the same directory as my .htm file.
This is my code so far.
<html>
<body>
<script type="text/javascript" src="lastfm.api.md5.js"></script>
<script type="text/javascript" src="lastfm.api.js"></script>
<script type="text/javascript" src="lastfm.api.cache.js"></script>
<script type="text/javascript">
var cache = new LastFMCache();
var lastfm = new LastFM({
apiKey : 'c9946d11aaaaaaaaaaaaaaaaaaaaaaaace',
apiSecret : '9dabf9aaaaaaaaaaaaaaaaxxx11ec3c7a993',
cache : cache
});
lastfm.artist.getInfo({artist: 'The xx'}, {success: function(data){
/* Use Data */
}, error: function(code, message){
/* Show error message. */
}});
</script>
</body>
</html>
I've dug around in the included .js files to try and understand what is going on. So on my initialization of lastfm, I am passing in some objects with associated values, which are then applied to lastfm. If I try and access them through document.write(lastfm.apiKey) I get an undefined value, which I don't really understand.
Also I see that I am calling getInfo and passing in 'The xx' and everything that follows. I don't understand how to use that Data that I believe is returned as a JSON response. How can I print the bio that is associated with that artist?
the code that should go where you have written /* Use Data */ will refer to items such as data.bio. Try alert(data) to see what's in there.
I would also highly recommend using a JavaScript debugging console such as FireBug in order to really see what's going on.
i just used this, and yeah. you just need to console.log(data) in the success to get info about the data that is being passed back from last fm

Categories