I am trying to render my riot tags on the server side and this works fine. The tags gets rendered on the server side and gets loaded on the client. Problem arises when I try to define my tags along with the definition of my routes using riot.route. The tags gets compiled to its corresponding Js files but on hitting my route it hits an internal server error and the error logged in the console is riot.route is not a function.
Code for my riot route in the script section of my tag.
<script>
var self = this;
this.data = opts.datastore
this.page = opts.datastore[0]
riot.route(function(id)
{
this.page = this.data.filter(function(r) { return r.id == id })[0] || {}
this.update();
})
this.doUpdate = function update()
{
opts.remarks = this.fname.value;
}
</script>
The data here comes from my server.js file via the datastore option and is a json data.
Related
Been trying to get my head around this, but can't for the life of me figure out what I'm missing.
So I want to set up keystone, but want to use angular on the front end, and I want to avoid reloading the page every time.
Got angular running quite fine and pretty quickly. But now I am trying to set up the routes on the backend for the partials, and while I can manage to get them set up to answer, I can not get them to just send the partial, whatever I do it sends the whole page back to me. with html, body, head.
So far I have managed to figure out that I need a route, so imported my uiview directory and added the following route:
var keystone = require('keystone');
var middleware = require('./middleware');
var importRoutes = keystone.importer(__dirname);
// Common Middleware
keystone.pre('routes', middleware.initLocals);
keystone.pre('render', middleware.flashMessages);
// Import Route Controllers
var routes = {
views: importRoutes('./views'),
uiviews: importRoutes('/uiviews'),
};
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
app.get('/', routes.views.index);
app.get('/uiviews/index',routes.uiviews.index);
app.get('/blog/:category?', routes.views.blog);
app.get('/blog/post/:post', routes.views.post);
app.get('/gallery', routes.views.gallery);
app.all('/contact', routes.views.contact);
// NOTE: To protect a route so that only admins can see it, use the requireUser middleware:
// app.get('/protected', middleware.requireUser, routes.views.protected);
};
I think what is happening is that the pre compiler ( keystone.pre('routes', middleware.initLocals);) gets hold of it and wraps it all the way it thinks it is suppose to, but I'm not certain.
I even tried to create a uiviews.js in ./routes with just my uiroute, but that gives me 404 errors
var keystone = require('keystone');
var middleware = require('./middleware');
var importRoutes = keystone.importer(__dirname);
// Import Route Controllers
var routes = {
uiviews: importRoutes('/uiviews'),
};
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
console.log('uiroutes added');
app.get('/uiview/index',routes.uiviews.index);
// NOTE: To protect a route so that only admins can see it, use the requireUser middleware:
// app.get('/protected', middleware.requireUser, routes.views.protected);
};
Any ideas?
This is more of a Express question and not of keystone.Js.
You have not said which router you want partially. and neither shared rendering code of that handler.
Any way Make sure that the template you are using does not include any other template. particularly default.jade
I finally managed to figure out what I was missing.
Technically it is not keystone.js that controls what is sent, it is handlebars. This might be obvious to everyone but me.
However, the trick is to tell handlebars not to include the layout, which is done using {layout: false}. So my uiview route looks like this (last little line does the magic):
var keystone = require('keystone');
exports = module.exports = function(req, res) {
console.log("request for index received");
var view = new keystone.View(req, res),
locals = res.locals;
console.log(locals);
// Render the view
console.log(view)
view.render('uiviews/index', {layout: false});
};
with the index.js router looking like this:
var keystone = require('keystone');
var middleware = require('./middleware');
var importRoutes = keystone.importer(__dirname);
// Common Middleware
keystone.pre('routes', middleware.initLocals);
keystone.pre('render', middleware.flashMessages);
// Import Route Controllers
var routes = {
views: importRoutes('./views'),
uiviews: importRoutes('/uiviews'),
};
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
console.log('index added');
app.get('/', routes.views.index);
app.get('/partners', routes.views.partners);
app.get('/blog/:category?', routes.views.blog);
app.get('/blog/post/:post', routes.views.post);
app.get('/gallery', routes.views.gallery);
app.get('/philosophy', routes.views.philosophy)
app.get('/socialmedia', routes.views.socialmedia)
app.all('/contact', routes.views.contact);
app.get('/uiviews/index', routes.uiviews.index)
// NOTE: To protect a route so that only admins can see it, use the requireUser middleware:
// app.get('/protected', middleware.requireUser, routes.views.protected);
};
And now you can call [host]/uiviews/index and only receive a partial route.
I am building the scaffolding for my new polymer project, and am considering unit tests. I think I will be using the karma/jasmine combination. There is an interesting post at http://japhr.blogspot.co.uk/2014/03/polymer-page-objects-and-jasmine-20.html which I understand enough to get me started, but the key question I will have to address and haven't found any standard way to do it is how do I mock the ajax calls.
When I was using jasmine, standalone, on a JQuery Mobile project, I was able to directly use the Jasmine SpyOn ability to mock the JQuery.ajax call. Is there something similar for Polymer?
I came across an element <polymer-mock-data> but there is no real documentation for it, so I couldn't figure out if they might help
Instead of importing core-ajax/core-ajax.html, create your own core-ajax element.
<polymer-element name="core-ajax" attributes="response">
<script>
Polymer('core-ajax', {
attached: function() {
this.response = ['a', 'b', 'c'];
}
});
</script>
</polymer-element>
Obviously, this is just an example, the actual implementation depends on the desired mocking behavior.
This is just one way to solve it, there are many others. I'm interested to hear what you find (in)convenient.
It turns out that Jasmine2.0 has an Jasmine-ajax plugin that will mock the global XMLHttpRequest. core-ajax uses this under the hood, so I can directly get at the call.
It works well, in a beforeEach function at the top the suite you call jasmine.Ajax.install and in the afterEach function you call jasmine.Ajax.uninstall, and it automatically replaces the XMLHttpRequest.
Timing is also crucial, in that you need to ensure you have mocked the Ajax call before the element under test uses it. I achieve that using a separate function to specifically load the fixture which contains the element under test, which is called after jasmine.Ajax.install has been called. I use a special setup script thus
(function(){
var PolymerTests = {};
//I am not sure if we can just do this once, or for every test. I am hoping just once
var script = document.createElement("script");
script.src = "/base/components/platform/platform.js";
document.getElementsByTagName("head")[0].appendChild(script);
var POLYMER_READY = false;
var container; //Used to hold fixture
PolymerTests.loadFixture = function(fixture,done) {
window.addEventListener('polymer-ready', function(){
POLYMER_READY = true;
done();
});
container = document.createElement("div");
container.innerHTML = window.__html__[fixture];
document.body.appendChild(container);
if (POLYMER_READY) done();
};
//After every test, we remove the fixture
afterEach(function(){
document.body.removeChild(container);
});
window.PolymerTests = PolymerTests;
})();
The only point to note here is that the fixture files have been loaded by the karma html2js pre-processor, which loads them into the window.__html__ array, from where we use the code to add to the test context
My test suite is like so
describe('<smf-auth>',function(){
beforeEach(function(done){
jasmine.Ajax.install();
PolymerTests.loadFixture('client/smf-auth/smf-auth-fixture.html',done);
});
afterEach(function(){
jasmine.Ajax.uninstall();
});
describe("The element authenticates",function(){
it("Should Make an Ajax Request to the url given in the login Attribute",function(){
var req = jasmine.Ajax.requests;
expect(req.mostRecent().url).toBe('/football/auth_json.php'); //Url declared in our fixture
});
})
});
For this answer, I took an entirely different approach. Inspiration came from Web Component Tester, which includes sinon within its capabilities. sinon includes the ability to call sinon.useFakeXMLHttpRequest to replace the standard xhr object that core-ajax uses and return responses baked on that.
As far as I can see, haven't quite got as far as running module tests using it, Web Component Tester runs sinon in the node.js context so the build of sinon supplied with it can "require" the various sinon components. In a normal browser environment this doesn't work and I was looking for a way to allow me to manually run the app I was developing without a php capable server running..
However, downloading and installing with Bower the actual releases from the sinonjs.org web site, does provide a completely built sinon that will run in the context of a web server.
So I can include the following scripts in my main index.html file
<!--build:remove -->
<script type="text/javascript" src="/bower_components/sinon-1.14.1/index.js"></script>
<script type="text/javascript" src="/fake/fake.js"></script>
<!--endbuild-->
which is automatically removed by the gulp build scrips and then fake JS has the following in it
var PAS = (function (my) {
'use strict';
my.Faker = my.Faker || {};
var getLocation = function(href) {
var a = document.createElement('a');
a.href = href;
return a;
};
sinon.FakeXMLHttpRequest.useFilters = true;
sinon.FakeXMLHttpRequest.addFilter(function(method,url){
if(method === 'POST' && getLocation(url).pathname.substring(0,7) === '/serve/') {
return false;
}
return true;
});
var server = sinon.fakeServer.create();
server.autoRespond = true;
my.Faker.addRoute = function(route,params,notfound){
server.respondWith('POST','/serve/' + route + '.php',function(request){
var postParams = JSON.parse(request.requestBody);
var foundMatch = false;
var allMatch;
/*
* First off, we will work our way through the parameter list seeing if we got a parameter
* which matches the parameters received from our post. If all components of a parameter match,
* then we found one
*/
for(var i=0; i <params.length; i++) {
//check to see parameter is in request
var p = params[i][0];
allMatch = true; //start of optimisic
for(var cp in p ) {
//see if this parameter was in the request body
if(typeof postParams[cp] === 'undefined') {
allMatch = false;
break;
}
if(p[cp] !== postParams[cp]) {
allMatch = false;
break;
}
}
if (allMatch) {
request.respond(200,{'Content-Type':'application/json'},JSON.stringify(params[i][1]));
foundMatch = true;
break;
}
}
//see if we found a match. If not, then we will have to respond with the not found option
if (!foundMatch) {
request.respond(200,{'Content-Type':'application/json'},JSON.stringify(notfound));
}
});
};
return my;
})(PAS||{});
/**********************************************************************
Thses are all the routinee we have and their responses.
**********************************************************************/
PAS.Faker.addRoute('logon',[
[{password:'password1',username:'alan'},{isLoggedOn:true,userID:1,name:'Alan',token:'',keys:['A','M']}],
[{username:'alan'},{isLoggedIn:false,userID:1,name:'Alan'}],
[{password:'password2',username:'babs'},{isLoggedOn:true,userID:2,name:'Barbara',token:'',keys:['M']}],
[{username:'babs'},{isLoggedIn:false,userID:2,name:'Barbara'}]
],{isLoggedOn:false,userID:0,name:''});
The PAS function initialises a sinon fake server and provides a way of providing tests cases with the addRoute function. For a given route, it checks the list of possible POST parameter combinations, and as soon as it finds one, issues that response.
In this case testing /serve/logon.php for various combinations of username and password. It only checks the parameters actually in the particular entry.
So if username = "alan" and password = "password1" the first response is made, but if username is "alan" and any other password is supplied - since it isn't checked, the second pattern matches and the response to that pattern is made.
If non of the patterns match, the last "notfound" parameter is the response pattern that is made.
I believe I could use this same technique in my module test fixtures if I wanted to, but I am more likely to do more specific sinon spying and checking actual parameters in that mode
For 0.8, the tests for PolylmerElements/iron-ajax show how to do this with sinon.
Since SO doesn't like link-only answers, I've copied their code below. However I'd highly recommend going to the source linked above, since 0.8 components are in a high state of flux currently.
var jsonResponseHeaders = {
'Content-Type': 'application/json'
};
var ajax;
var request;
var server;
setup(function () {
server = sinon.fakeServer.create();
server.respondWith(
'GET',
'/responds_to_get_with_json',
[
200,
jsonResponseHeaders,
'{"success":true}'
]
);
server.respondWith(
'POST',
'/responds_to_post_with_json',
[
200,
jsonResponseHeaders,
'{"post_success":true}'
]
);
ajax = fixture('TrivialGet');
});
teardown(function () {
server.restore();
});
suite('when making simple GET requests for JSON', function () {
test('has sane defaults that love you', function () {
request = ajax.generateRequest();
server.respond();
expect(request.response).to.be.ok;
expect(request.response).to.be.an('object');
expect(request.response.success).to.be.equal(true);
});
test('will be asynchronous by default', function () {
expect(ajax.toRequestOptions().async).to.be.eql(true);
});
});
I'm trying to Implement a simple Picture upload from the client to my mongoDB.
I've read many explanations but I can't find a way from start to finish.
My clientside -
function profilePic(input) {
if (input.files && input.files[0]) {
var file = input.files[0];
localStorage.setItem('picture', JSON.stringify(file));
}
}
Later on I take the this JSON from the LocalStorage and send it to my server side like this:
var request = false;
var result = null;
request = new XMLHttpRequest();
if (request) {
request.open("POST", "usersEditProf/");
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
.....//More code to send to Server
request.setRequestHeader('content-type', 'application/json');
request.send(JSON.stringify(localStorage.getItem('picture)));
}
}
On my serverside:
app.post('/usersEditProf/',users.editProfile);
/** Edits the Profile - sends the new one **/
exports.editProfile = function(req, res) {
var toEdit = req.body;
var newPic = toEdit.picture;
And thats where I get lost. is newPic actually holding the picture? I doubt it...
Do I need to change the path? What is the new path I need to give the picture?
How do I put it in my DB? Do I need GridFS?
When trying to simply put that in my collection, it looks like this (example with a image called bar.jpg:
picture: "{\"webkitRelativePath\":\"\",\"lastModifiedDate\":\"2012-10-08T23:34:50.000Z\",\"name\":\"bar.jpg\",\"type\":\"image/jpeg\",\"size\":88929}",
If you want to upload a blob through XMLHTTPRequest(), you need to use an HTML 5 FormData object:
https://developer.mozilla.org/en-US/docs/Web/API/FormData
It alows you to specify a filename to push, then you handle the incoming file as you would with a mime form post. Note the limitations on browser support when you use the FormData object. Your alternative is a form POST to a hidden frame, which works OK but is not nearly as clean looking in code as FormData.
I have searched in this forum for quiet a bit and here's my problem -
I have a ng-repeat in my html which takes in a list of messages(Json object).
Each message JSON has a sender email address - e.g. abc#gmail.com
Now, I have to get the email address from the message and form another REST API request to fetch their images for e.g. - http://<>:8080/getImage/abc#gmail.com (email address dynamic)
So in my code, I'll have a ng-repeat and a ng-src pointing to the image REST URL
If there's no image in server, it returns a 404 and displays a broken image on the UI. How do I handle it? On the other hand, if I make a http request to determine if there's a success message and on failure return a default image, then the whole thing goes through an endless loop. I'll try to create a fiddle and include it for better explanation.
Use the error block to handle such behavior:
function($http) {
var restUrl = 'getImage/abc';
return {
fetchImage: function(imageId) {
var self = this;
return $http.get(restUrl + '/' + imageId).
success(function(data) {
return self.imageUrl = data;
}).
error(function(data) {
return self.imageUrl = "pathToDefaultImage";
});
},
...
I have a Javascript component that when the DOM is loaded it needs to send a request out to our CDN, which may be in a different domain, to see if there is content for this component. If there is, the component will self-instantiate (its a link to open an embedded video in a modal), if not it will self destruct. My question is mainly about the Grails controller I am using to proxy the AJAX request.
Here is the JS in pseudocode:
checkForVideoAssets: function(videoDataUrl){
Ajax.get(videoDataUrl, function(data){
if(data.responseText==='error'){
//tear down the component
}
else{
//if there is data for the video instantiate the component
}
Here is the Grails controller:
def checkForModalVideoAsset = {
def req = new URL("http://" + params.videoUrl + "/expense/videos/")
def connection = req.openConnection()
if(connection.responseCode != 200){
render 'error'
}
if(connection.responseCode == 200){
render req.getText()
}
}
So, to sum up, the JS grabs an attribute from the DOM that has part of a URL (that we define by convention), sends that URL to the controller, the controller attempts to connect to that URL (at our CDN) and then passes that response back to the AJAX success callback inside the responseText part of the XHR object. This feels less than ideal to me, is it possible to pass the actual response back up to the JS function?
The httpbuilder may be usefull to you
I never tried it but something similar!?
def checkForModalVideoAsset = {
def http = new HTTPBuilder("http://" + params.videoUrl )
http.get(
path : "/expense/videos/",
contentType : TEXT ) { resp, reader ->
response.properties=resp.properties //<-- to easy to work but why not try :)
response << resp
}
}