How to send a JSON data to event push? - events

I am using the events push plugin for grails.
Everything is working fine when I push simple data like this:
def mydata = [:]
mydata.message = "hello world"
event (topic: 'mySaved', data: mydata)
I can display this on my page like this:
grailsEvents.on('mySaved', function (data) {
console.log(data);
console.log(data.message)
}
However, I want to send a whole instance to this topic and thats when it breaks.
So, for example:
def mydata = colorInstance as JSON
println mydata
event (topic: 'mySaved', data: mydata)
The above println prints this:
{"id":10,"color":"Red","description":"hot color"}
If I try to use it on my page like this:
grailsEvents.on('mySaved', function (data) {
console.log(data);
console.log("This is ID: " + data.id)
}
I don't get the desired result. The above prints the following in the console log:
Object {class: "grails.converters.JSON", depth: 0, writer: Object}
This is ID: undefined
Question
How can I send the colorInstance so that I can fetch it in the console?

Try pushing
event( topic: 'mySaved', data: mydata.toString() )

Related

Retrieve post variable sent via Ajax in Django

I'm processing a table of banking/statement entries that have been exported from another system via a CSV file. They are imported into a view and checked for duplicates before being presented to the user in a HTML table for final review.
Once checked they are sent via AJAX to the server so they can be added into a Django model. Everything is working OK including CSRF but I cannot access the POSTed variable although I can see it!
Unfortunately making a hidden form isn't viable as there are 80+ rows to process.
My Javascript looks like:
$.ajax({
type: 'POST',
url: '......./ajax/handleImports/',
data: entriesObj,
success: function (data) {
if (data.response && data.response) {
console.log("Update was successful");
console.log(data.entries)
} else { ... }
},
error: function() { ... }
where entriesObj is
var entriesObj = JSON.stringify({ "newentries": newEntries });
console.log(entriesObj)
and when dumped to console.log looks like:
{"newentries":[{"Include":"","Upload ID":"0","Date":"2019-01-09", ... }
Now in view.py when I return the whole request.POST object as data.entries using
context['entries'] = request.POST
return JsonResponse(context)
I get
{"{"newentries":[{"Include":"","Upload ID":"0","Date":"2019-01-09", ... }
but if I try and retrieve newentries with:
entries = request.POST.get('newentries', None)
context['entries'] = entries
return JsonResponse(context)
the console.log(data.entries) will output null?
How am I supposed to access the POSTed entriesObj?
The data is JSON, you need to get the value from request.body and parse it.
data = json.loads(request.body)
entries = data.get('newentries')

How can I read a local file in Cloud Code as a string?

I'm using Parse Cloud Code.
My system has a welcome message. I use MailGun to send it.
The problem I have is that the message now is an HTML file, so I would like to let the HTML file in my server, read it using Cloud Code and pass that info to MailGun.
Can I read a local text file using Cloud Code and have it in my program as a string?
Should I save that file in my public folder or in the same folder than my cloudcode program?
I'm not confident with MailGun, but I believe it should work like MailChimp or Mandrill. If so, you should be able to store on MailGun your whole HTML template and just have some template_vars to complete.
This is a sample code of our own way to send mail with HTML thanks to the Mandrill system
Parse.Cloud.define("sendMailTemplate", function(request, response) {
var emails = request.params.emails;
var template_name = request.params.template_name;
var template_merge_content = request.params.template_merge_content;
var subject = request.params.subject;
var Mandrill = require('cloud/mandrillTemplateSend.js');
if (subject === undefined) {
subject = 'Mail sent by Mandrill';
body = subject;
}
Parse.Config.get().then(function(config) {
Mandrill.initialize(config.get('Mandrill_key'));
}).then(function() {
_.each(emails, function(email) {
Mandrill.sendTemplate({
template_name: template_name,
template_content: [{
name: template_merge_content.username,
content: ''
}],
message: {
text: '',
subject: subject,
from_email: 'contact#yourdomain.com',
to: [{
email: email,
name: template_merge_content.username
}],
merge_vars: [{
rcpt: email,
vars: template_merge_content
}],
},
async: false
});
});
}).then(function() {
response.success('Success');
}, function(error) {
response.error(error);
});
});
This object template_merge_content is quiet important. It's an object where is saved all the dynamic vars which are send to complete your HTML mail.
According to http://blog.mailgun.com/transactional-html-email-templates/ it seems you have same kind of method to send your mail.
So final advice would be to NOT store your HTML template within any Parse's class, or to save it within https://parse.com/docs/js/api/symbols/Parse.Config.html

Django, Ajax- HttpResponse does not send json

Django 1.7.2/ python 3.4
this code is about 'like'.
if user click the 'like' button, ajax calls 'pushLike'.
if the user has liked the article before(saved inside Mysql), delete the row on table(DB).
or if the user is not liking the article, create a row and insert it on the table(DB).
after that, count how many like has beed clicked on that article.
I would like to pass the likeCnt(count) to ajax, and write it on the button.
The likeCnt has the right value(I checked it on the server mysql table).
The button color does change(white to blue, and vise versa), but the text does not change.
It seems like json does not pass to ajax. I tried passing data by 'text' type and it did worked, but i want it by json.
I've tried simplejson, json, mimetype, content_type on HttpResponse.
please help me.
view
#login_required
def pushLike(request):
pk = request.GET['writing_id']
try:
la = LikeArticles.objects.get(user = User.objects.get(username=request.user.username), article_id=pk)
if(la.is_like()):
la.delete()
likeCnt = LikeArticles.objects.filter(article_id=pk).count()
FreeBoards.objects.filter(id=pk).update(like = likeCnt)
else: #Never happens
la.like = True
la.save()
likeCnt = LikeArticles.objects.filter(article_id=pk).count()
FreeBoards.objects.filter(id=pk).update(like = likeCnt)
except ObjectDoesNotExist:
la = LikeArticles(user = User.objects.get(username=request.user.username),
article = FreeBoards.objects.get(id=pk),
like = True,
)
la.save()
likeCnt = LikeArticles.objects.filter(article_id=pk).count()
FreeBoards.objects.filter(id=pk).update(like = likeCnt)
data = {'likeCnt': likeCnt}
# return render(request, url, context)
return HttpResponse(simplejson.dumps(data), mimetype='application/javascript')
javascript
<script type="text/javascript">
$(document).ready(function(){
$('#btn-like').click(function(){
var e = $('#btn-like').css('background-color');
$.ajax({
url : '/sle/freeboards/pushLike/',
data : {'writing_id':{{writing_id}},
},
dataType : "json",
success:function(data){
alert(data.likeCnt);
if(e == 'rgb(59, 89, 152)') {
$('#btn-like').css('background-color', '#ffffff').css('color', '#000000');
$('#btn-like').text(data.likeCnt);
} else {
$('#btn-like').css('background-color', '#3b5998').css('color', '#ffffff');
$('#btn-like').text(data.likeCnt);
}
},
failure: function(data){
alert('fail!!')
}
});
});
});
</script>
you'll want to be sure to set the proper mimetype in your HttpResponse
#login_required
def pushLike(request):
...
# return json -- !!not javascript!!
return HttpResponse(simplejson.dumps(...), mimetype="application/json")
--or--
#login_required
def pushLike(request):
...
# return json -- !!not javascript!!
return JsonResponse({"your": "context dictionary"})
If that doesn't work, have you tried parsing the json with your Jquery code?
ie:
$.ajax({
...
success: function(data){
var response = $.parseJSON(data);
...
}
});
javascript might actually receiving bytes back from whatever you are serving your django app with... so instead of getting JSON back, you're actually getting string that looks like JSON. http://api.jquery.com/jquery.parsejson/

Parse Cloud Code afterSave not working

Hey I'm using Parse as my backend and I love it but I have a problem with the afterSave hook.
Here is the Code I'm using:
Parse.Cloud.afterSave ("JGZwoelf",function (request) {
Parse.Push.send({
//Selecting the Channel
channels: [ request.object.get('JGZwoelfPush') ],
data: {
//Selecting the Key inside the Class
alert: request.object.get('AusfallInfo')
}
}, {
success: function () {
//Push was send successfully
},
error: function (error) {
//Handle error
throw "Got an error" + error.code + " : " + error.message;
}
});
});
Every time the logs console is telling me: Result:
Uncaught Got an error112 : Missing channel name.
I just don't understand what is wrong! It must be in that JavaScript code. If I enter the push notification manually everything works fine :/
Edit:
The part Parse.Push.send should look like this:
Parse.Push.send ({
//Selecting the already existing Push Channel
channels: ["JGAchtPush"], //This has to be the name of your push channel!!
data: {
//Selecting the Key inside the Class
alert: request.object.get ("AusfallInfo")
}
}, {
success: function () {
//Push was sent successfully
//nothing was loged
},
error: function (error) {
throw "Got and error" + error.code + " : " + error.message;
}
});
The channel name needs to be something like ["exampleChannel"].
Thanks in advance for any given help :)
The first argument to afterSave should be a class name, not an objectId.
following is for new folks (like me), it is the exact same code in original question, plus a few more comments, plus the correction from accepted answer. purpose is to show example of what few pieces of code need changing for this to work in your parse cloud code. thank you Constantin Jacob and bklimt.
Parse.Cloud.afterSave ("UserVideoMessage",function (request) { // name of my parse class is "UserVideoMessage"
Parse.Push.send ({
//Selecting the already existing Push Channel
channels: ["admin"], //This has to be the name of your push channel!!
data: {
//Selecting the Key inside the Class, this will be the content of the push notification
alert: request.object.get ("from")
}
}, {
success: function () {
//Push was sent successfully
//nothing was loged
},
error: function (error) {
throw "Got and error" + error.code + " : " + error.message;
}
});
});

Grails - Fails to submit base64 img

I need to make ajax submit to submit some data include a base64 string of the image, which is render from canvas.
When submit I look in the network panel of Chrome inspector and everything look fine, in "form data" it list all the data that I want to submit.
But in Grails I cannot get the data, there is nothing in the params, just the controller name and action name. Thus everything I get with simple params.dataName is null.
I guess there is something with the size of the post request, but I'm not so sure as I have done this before without ajax.
This is my code for upload with jquery ajax:
var imgBase64String = canvas.toDataURL("image/png");
imgBase64String = imgBase64String .replace('data:image/png;base64,', '');
var submitData = $(form).serializeArray();
submitData.push({name: "webImage", value: imgBase64String })
$.ajax({
type: 'POST',
url: '${createLink(action: 'myAction')}',
data: submitData,
dataType: "html",
success: function(data){//Success code},
});
UPDATE
My code on the server side, it fails at the simple step to retrieve params data:
def myAction= {
def paramData = params
log.info "paramData: " + paramData
def url = params.url
def email = params.email
def webImage = params.webImage
log.info "param: url = " + url
log.info "param: email = " + email
log.info "param: webImage = " + webImage
//Other implement code
}
And the output:
2012-10-08 16:31:28,988 [http-bio-8080-exec-5] INFO myController - paramData: [action:myAction, controller:myController]
2012-10-08 16:31:28,989 [http-bio-8080-exec-5] INFO myController - param: url = null
2012-10-08 16:31:28,989 [http-bio-8080-exec-5] INFO myController - param: email = null
2012-10-08 16:31:28,989 [http-bio-8080-exec-5] INFO myController - param: webImage = null
The size of the base64 image I'm trying to submit is 1998720, don't know if this matter.
Many thanks.
I believe you can simply pass canvas.toDataURL("image/png") into the data field in the $.ajax() method. Also use $.post() instead of $.ajax(). So your code should look like this in the js file:
$.post('/image/getCanvasImage', //this is your url
{
img : canvas.toDataURL('image/jpeg'),
email : email
}, function(data){
//whatever you wanna do with the returned data
}
);
Then in your action, import import sun.misc.BASE64Decoder package and you can write this code to save the canvas image:
def file = params.img.toString().substring((params.img.toString().indexOf(",")+1),params.img.toString().size())
byte[] decodedBytes = new BASE64Decoder().decodeBuffer(file)
def image = new File("mySavedImage.jpg")
image.setBytes(decodedBytes)
Should work!

Resources