I am using hbs as view in frontend.
I tried to send data to my script in html from nodejs like this :
router.get('/home',authController.isLoggedIn, (req ,res) => {
if(req.user){
db.query('SELECT * FROM posts ORDER BY id desc ', (error,results) => {
if (error) {
console.log(error);
} else {
let categories;
db.query('SELECT * FROM categories', (error,result) => {
if (error) {
console.log(error);
} else {
console.log(result);
categories = result;
return res.render('home',{
results: results,
categories: categories
});
}
});
}
});
}else {
res.redirect('/login');
}
});
then when i am trying to call it here in script using javaScript it tells me something is wrong
<script>
alert(results);
</script>
I want to know how correctly call the the object in script
edit:
the data should be something like this :
[
RowDataPacket { id: 1, category: 'Music' },
RowDataPacket { id: 2, category: 'Memes' },
RowDataPacket { id: 3, category: 'Tech' }
]
For EJS example if pass data msgs:
res.render("index.ejs", {
msgs
})
js handle data:
<p>
<%
msgs = msgs.map(function(msg) {
return '<div>' + msg.name + '</div>' + '<div>' + msg.msg + '</div>'+ '<div>' + msg.time + '</div>'
})
%>
</p>
print directly:
<p><%- msgs.join("<hr />") %></p>
save in global variable
<script>
window.serverMsgs = <%- msgs %>;
</script>
And for handlebars:
<script>
window.serverMsgs = {{msgs}};
alert(window.serverMsgs)
{{#each results}}
{
"id": {{id}},
"category": "{{category}}",
}
{{#unless #last}},{{/unless}}
{{/each}}
</script>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>{{title}} - Page Test</title>
</head>
<body>
<div class="description">{{description}}</div>
<ul>
{{#datas}}
<li class="item" id="item_{{index}}"><span>{{time}}</span>{{title}}</li>
{{/datas}}
</ul>
</body>
</html>
u could check out this similar issue:) How to define an array within a <script> tag inside a hbs view template
Related
I have the code below and have 2 separate issues, so please bear with me on this:
Issue 1 [fetch ?]:
The data displayed doesn't change when the JSON change. Sounds like it's a cache issue as I can't see any HTTP request beside the original one. How can I force the JSON file to be downloaded again each time?
Issue 2 [handlebars ?]: with $(document.body).append(html); in the loop, it keeps re-writing the instead of editing the values. How can I change this?
Here is the code:
javascript.js:
async function fetch_json() {
try {
var resp = await fetch('http://localhost:8000/data.json', {mode: 'cors'});
var jsonObj = await jsonify(resp);
return jsonObj;
} catch (error) {
// all errors will be captured here for anything in the try block
console.log('Request failed', error);
}
}
html page:
<script id="handlebars-demo" type="text/x-handlebars-template">
<div>
{{#each this}}
Name : {{name}} Value : {{value}} <br>
{{/each}}
</div>
</script>
<script type="text/javascript">
var test_data = [{ "name" : "john doe", "value" : "developer" },{ "name" : "bob boby", "value" : "developer2" }];
setInterval(function() {
test_data = fetch_json()
.then(function(result) {
html = templateScript(result);
//$(document.body).append(html);
})
}, 1000);
var template = document.getElementById('handlebars-demo').innerHTML;
Compile the template data into a function
var templateScript = Handlebars.compile(template);
var html = templateScript(test_data);
$(document.body).append(html);
</script>
any help would be the most appreciated, thank you!
You should create a DOM element to hold the HTML you are generating. I've created <div id="content"></div> in the example.
You can use $().html() to overwrite the HTML each time instead of appending.
$('#content') selects the DOM element with id=content and then overwrite the HTML inside .html(string) with string.
A common approch to cache busting is to attach a timestamp to the url as a url query param, which I have done by concatenating nocache='+new Date().getTime().
In normal use in production a unique identifier is usually generated per version for each resource after building.
// for demo purposes, overwrite value property with username property
jsonify = x => x.json().then(x => x.map(x => ({ ...x,
value: x.username
})));
async function fetch_json() {
try {
// append timestamp to prevent caching
var resp = await fetch('https://jsonplaceholder.typicode.com/users?nocache=' + new Date().getTime(), {
mode: 'cors'
});
var jsonObj = await jsonify(resp);
return jsonObj;
} catch (error) {
// all errors will be captured here for anything in the try block
console.log('Request failed', error);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.6/handlebars.js" integrity="sha256-ZafrO8ZXERYO794Tx1hPaAcdcXNZUNmXufXOSe0Hxj8=" crossorigin="anonymous"></script>
<div id="content"></div>
<script id="handlebars-demo" type="text/x-handlebars-template">
<div>
{{#each this}} Name : {{name}} Value : {{value}} <br> {{/each}}
</div>
</script>
<script type="text/javascript">
var test_data = [{
"name": "john doe",
"value": "developer"
}, {
"name": "bob boby",
"value": "developer2"
}];
setInterval(function() {
test_data = fetch_json()
.then(function(result) {
html = templateScript(result);
$('#content').html(html);
})
}, 2000);
var template = document.getElementById('handlebars-demo').innerHTML;
//Compile the template data into a function
var templateScript = Handlebars.compile(template);
var html = templateScript(test_data);
$('#content').html(html);
</script>
I want show elastic search data on web page that using angular js.
however, not bring data from elasticsearch with that message
Is there anything I need to add or fix in my code?
if anyone answers to me I really appreciate
I have attached an execution screen.
thank you.
Execution screen:
enter image description here
<!doctype html>
<html ng-app="myApp">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<div ng-controller="QueryController"></div>
<script src="node_modules/angular/angular.js"></script>
<script src="node_modules/elasticsearch-browser/elasticsearch.angular.js"></script>
<script>
var myApp = angular.module('myApp', ['elasticsearch']);
// Create the es service from the esFactory
myApp.service('es', function (esFactory) {
return esFactory({ host: 'http://localhost:9200'});
});
myApp.controller('ServerHealthController', function($scope, es, esFactory) {
es.cluster.health(function (err, resp) {
if (err) {
$scope.data = err.message;
} else {
$scope.data = resp;
}
});
});
// We define an Angular controller that returns query results,
// Inputs: $scope and the 'es' service
myApp.controller('QueryController', function($scope, es, esFactory) {
// search for documents
es.search({
index: 'epowersyst',
type: 'logs',
body: {
query:
{
"match_all" : {} }
}
}).then(function (response) {
$scope.hits = response;
console.log($scope.hits)
}).catch(function (err) {
if (err.status === 404) {
alert("error 404" );
} else {
alert("error : " + err );
}
});
});
</script>
</body>
</html>
Looking to change a Jade assigned variable with the results of an ajax post so that the page's Jade loop utilizes the new data (updating only the parts of the dom that relate to the loop and not rendering the page over).
route.js
router.post('/initial', function(req, res) {
res.render('/page', {data: data})
})
router.post('/refresh', function(req, res) {
res.send(newdata)
})
index.jade
block content
- var fluxdata = data
each item in fluxdata
span= item
div#button
client.js
$(document).on('click', '#button', function() {
$.post('/refresh', function(newdata) {
var fluxdata = newdata
})
}
I tried out partials, but wasn't sure I was on the right track. Looked around the internet and stackoverflow for a while and can't find a similar question about Jade assignments.
// Jade template
block content
div(class="content")
- var fluxdata = data
each item in fluxdata
span #{item.id} : #{item.username}
div
button(id="add") POST Data
after your template is rendered your html will look like this
// HTML rendered
<div class="content">
<span>1 : Yves</span>
<span>2 : Jason</span>
</div>
<div>
<button id="add">POST DATA</button>
</div>
// backend code
var users = [
{
username: "Yves",
id: 1
},
{
username: "Jason",
id: 2
}
]
router.get("/initial", function(request, responser) {
response.render("index", { data: users})
})
router.post("/refresh", function(request, responser) {
users.push({username: "Alex",id: 1})
response.json({ data: users})
})
// Your jquery code
$("#button").on('click', function(event){
event.preventDefault()
$.post('/refesh', function(data) {
$(".content").html("")
for(var user in data) {
var span = $("<span>")
span.text(user.id + ": " + user.username )
$(".content").append(span)
}
});
})
in your get "/initial" route handler, your are rendering the
res.render("/page", {data : data })
before the template name you musn't put the / and the template in witch you are trying to use data that at push to the view is index.jade
router.post('/initial', function(req, res) {
res.render('index', {data: data})
})
I'm having problem with redirecting search results to page that I want to display results. Want to have search bar in header so that my results are displayed on results page or something similar. All was done by tutorial (Laracasts), still learning javascript, so I'm a bit stuck here.. Some help would be great!
index.blade.php
<script src="http://code.jquery.com/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>
<script src="http://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.1/vue.js"></script>
<script>
new Vue({
el: 'body',
data: {
query: '',
users: []
},
ready: function () {
this.client = algoliasearch('', '');
this.index = this.client.initIndex('test_drive_contacts');
$('#typeahead').typeahead(null, {
source: this.index.ttAdapter(),
displayKey: 'firstname',
templates: {
suggestion: function (hit) {
return '<div>' +
'<h4 class="high">' + hit._highlightResult.firstname.value + '</h4>' +
'<h5 class="high">' + hit._highlightResult.company.value + '</h5>'
+ '</div>';
}
}
})
.on('typeahead:select', function (e, suggestion) {
this.query = suggestion.firstname;
}.bind(this));
},
methods: {
search: function () {
this.index.search(this.query, function (error, results) {
this.users = results.hits;
}.bind(this));
}
}
});
</script>
This is the search input:
<input id="typeahead" type="text" class="form-control" v-model="query"
v-on="keyup: search | key 'enter'">
<article v-repeat="user: users">
<h2>#{{ user.firstname }}</h2>
<h4>#{{ user.company }}</h4
</article>
Redirecting users to a page in JavaScript is as easy as doing
window.location = 'your_url_here'
If you're just looking to redirect to a /search?q=query page when the user types Enter, that's as easy as wrapping the input you're using inside a form.
<form action="/search" method="GET">
<input type="search" id="your-input" name="q" />
</form>
If you want to redirect to an item page, the typeahead:select event gives you the selected option :
$('#your-input')
.typeahead(/* ... */)
.on('typeahead:select', function (e, suggestion) {
window.location = suggestion.url;
});
I'm getting the classic the classic Error: Unknown provider: UserModelProvider <- UserModel with angular JS. My code looks like this:
var ClabborApp = angular.module('clabbor', []);
ClabborApp.factory('UserModel', function() {
var UserModel = {};
var list = [];
UserModel.getItem = function(index) {
return list[index];
}
UserModel.addItem = function(item) {
list.push(item);
}
UserModel.removeItem = function(item) {
list.splice(list.indexOf(item), 1)
}
UserModel.size = function() {
return list.length;
}
return UserModel;
});
function FollowersCtrl($scope, UserModel) {
$scope.followers = [{
text : 'learn angular',
done : true,
'name' : 'James'
}, {
text : 'build an angular app',
done : false,
'name' : 'John'
}];
}
And my html looks like this:
<html lang="en" ng-app>
<meta charset="utf-8">
<body ng-app="clabbor">
<div class="content follow" ng-controller="FollowersCtrl">
<ul class="clearfix">
<!-- Show max 12 followers -->
<li ng-repeat="follower in followers">
{{follower.name}}
</li>
</ul>
</div>
</body>
</html>
I thought I did it by the book but I am getting the error. Does anyone know what could it be?
Remove the ng-app attribute from the html tag. Here's Jsfiddle that's working: http://jsfiddle.net/eA2xx/. You can't have more than one ng-app.