I am an absolute beginner in node.js and geddy. I've followed a few tutorials and now I try to write something similar for my purposes.
When I try to create a new item, though, I get the following message:
/arithmetic_problem_types/function%20(id)%20%7B%20%20%20%20%20%20options.id%20=%20id;%20%20%20%20%20%20return%20helpersBase.urlFor.action(options);%20%20%20%20%7D not found.
I have no idea where this could come from. I've looked through the code and found nothing.
Controller:
var ArithmeticProblemTypes = function () {
this.respondsWith =[ 'html', 'json', 'xml', 'js', 'txt'];
this.index = function (req, resp, params) {
var self = this;
geddy.model.ArithmeticProblemType.all(function (err, arithmetic_problem_types) {
self.respond({
params: params, arithmetic_problem_types: arithmetic_problem_types
});
});
};
this.add = function (req, resp, params) {
this.respond({
params: params
});
};
this.create = function (req, resp, params) {
var self = this, arithmetic_problem_type = geddy.model.ArithmeticProblemType.create({
name: '1', title: 'open', numberType: '1', numberRanges: '1', operators: '1', askedFor: '1', specialProblemCategory: '1', askedForNumDenomOrBoth: '1',
reducedFractions:'1', mixedFractions: '1'
});
arithmetic_problem_type.save(function (err, data) {
if (err) {
params.errors = err;
self.transfer('add');
} else {
self.redirect({
controller: self.name
});
}
});
};
....................................................................
};
exports.ArithmeticProblemTypes = ArithmeticProblemTypes;
add.html.ejs
<div class="hero-unit">
<%= partial('_form', {params: params}); %>
</div>
index.html.ejs
<div class="hero-unit">
<h2>Arithmetic Problem Types List</h2>
<%- linkTo('Create a new Aritmetic Problem Type', addArithmeticProblemTypePath, {class: 'btn pull-right'}) %>
</div>
<% if (arithmetic_problem_types && arithmetic_problem_types.length) { %>
<% for (var i in arithmetic_problem_types) { %>
<div class="row todo-item">
<div class="span8">
<h3><%- linkTo(arithmetic_problem_types[i].title, arithmeticProblemTypePath(arithmetic_problem_types[i].id)) %></h3>
</div>
<div class="span4"><h3><i class="icon-list-alt"></i><%= arithmetic_problem_types[i].status; %></h3></div>
</div>
<% } %>
<% } %>
How can I get rid of that message and make it work?
EDIT:
This is the beginning of the _form.html.ejs file:
<%
var isUpdate = params.action == 'edit'
, formTitle = isUpdate ? 'Update this Arithmetic Problem Type' : 'Create a new Arithmetic Problem Type'
, action = isUpdate ? arithmeticProblemTypePath(params.id) + '?_method=PUT' : arithmeticProblemTypePath
, deleteAction = isUpdate ? arithmeticProblemTypePath(params.id) + '?_method=DELETE' : ''
, btnText = isUpdate ? 'Update' : 'Add'
, nameValue = isUpdate ? arithmeticProblemTypePath.name : ''
, errors = params.errors;
%>
<form id="arithmetic-problem-type-form" class="form-horizontal" action="<%= action %>" method="POST">
....
</form>
EDIT2:
Inspecting the page where I should write the name of the item and click the add button, I've found this
<div class="hero-unit">
<form id="arithmetic-problem-type-form" class="form-horizontal" action="function (id) {
options.id = id;
return helpersBase.urlFor.action(options);
}" method="POST">
<fieldset>
<legend>Create a new Arithmetic Problem Type</legend>
<div class="control-group">
<label for="title" class="control-label">Title</label>
<div class="controls">
<input class="span6" name="name" placeholder="enter name" type="text">
</div>
</div>
<div class="form-actions">
<input class="btn btn-primary" type="submit" value="Add">
</div>
</fieldset>
</form>
</div>
Indeed the message comes from the action attribute of the form element, but how can I solve it?
The message is telling you that the requested URL could not be found. AKA 404
/arithmetic_problem_types/function%20(id)%20%7B%20%20%20%20%20%20options.id%20=%20id;%20%20%20%20%20%20return%20helpersBase.urlFor.action(options);%20%20%20%20%7D
is definitely not a nice looking url. So i'm assuming there's something wrong with your form's action attribute. If that's what happened when you validate the form.
If that's what happened when you click the link to "Create a new arithmetic problem type" then you should probably put parenthesis after addArithmeticProblemTypePath
Related
I'm making a site with handlebars and nodejs and I want to show a "message" (you can best compare them to tweets) only if the "message" is from a specific user.
For the if statement I used the following question asked on stackoverflow in the past: Logical operator in a handlebars.js {{#if}} conditional I'm passing through 2 variables: messages and username where username is a string and messages an array. I use message as |item| to get a specific place from the array. The username is stored in item.[0]. As I change the username in the value to "test" in line 3 of the hbs code so it would be {{#ifCond item.[0] "test"}} then it works, but not with the username passed through with the value.
Here's my handlebars code:
{{#if user}}
{{#each messages as |item|}}
{{#ifCond item.[0] username}}
<div class="card" style="width: 100%;">
<div class="card-body">
<h5 class="cardtitle">{{#key}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{item.[0]}}</h6>
<h6 class="card-subtitle mb-2 text-muted">{{item.[2]}}</h6>
<p class="card-text">{{item.[1]}}</p>
</div>
</div>
<p></p>
{{else}}
<p>{{item.[0]}}</p>
{{/ifCond}}
{{/each}}
{{/if}}
The node.js code to load the page:
router.get('/users',loggedIn,messages,(req, res) => {
var user = res.user
var username = req.query.user
var message = res.message
if (user != undefined){
res.render("publicprofile", {user:user, username:username, messages:message, usernamestr:String(username)})
} else{
res.redirect("/")
}
});
and the handlebars helper:
hbs.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
I will start off with how my mongoDB data looks like:
_id : 5c5b450918cb2b121648ff7a
name : "dannondarko"
email : "dangilmail#gmail.com"
password : "$2a$10$3z5m1e9Pcfid72Q2GchCjeTD55/SsIxmtWr3I1ZiA.DX/KlpfTbdK"
date : 2019-02-06 20:35:21.973
__v : 0
posts : Array
0 : Object
note : "test for the user dannondarko"
date : "02/08/2019"
This is just a side project and most likely will never be live so don't worry about the security of me posting this data! As for how I am procession the code in my server code:
app.get('/:username', (req, res) => {
username = req.params.username.toLowerCase();
const collection = req.app.locals.collection;
collection.find({ name: username }).toArray(function (err, results) {
if (err) {
res.status(500).send("Error communicating with the DB.");
} else if (results.length > 0) {
console.log("Here are the results: " + results);
console.log({people: results});
res.status(200).render('profile', {posts: results, name: username});
} else {
next();
}
});
});
What I am doing with this code is say you head to the address bar '/dannondarko', it should find 'dannondarko' in the collection, which it does fine, and then the 'results' variable is the complete object that I posted above. What I am trying to do is just get the 'posts' data, such as the note and date.
The note and date is the only data I need, which will be sent to this .ejs file that should create a post (kind of like FB) that shows the users' notes and date of the post. Here is my .ejs file:
<h1 class="mt-4"><%= name %></h1>
<div class="container">
<br>
<% for(var i=0; i < posts.length; i++) { %>
<div class="container">
<label><%= posts[i].note %></label>
<div class="container">
<label><%= posts[i].date %></label>
</div>
</div>
<% } %>
</div>
I hope that's enough information. I believe my downfall is not knowing how to just extract the 'posts' array from MongoDB from a certain user and iterate through the objects and sending over the note and date to the .ejs.
The results is an array of documents and you render this array to ejs as posts. Now in your ejs file posts represent the array of documents, not the posts array. So if you want to loop through all results you should edit your code like this:
<% posts.forEach(post => { %>
<h1 class="mt-4"><%= post.name %></h1>
<div class="container">
<br>
<% post.posts.forEach(p => { %>
<div class="container">
<label><%= p.note %></label>
<div class="container">
<label><%= p.date %></label>
</div>
</div>
<% }) %>
</div>
<% }) %>
If i understand well your mongo model structure the above should help you.
I have a vue component which prints out a list of radio buttons. I have a watch on internalValue which sends the selected value to the root
I am trying to send a console.log on a click event using a method called doSomething but it is not working. Furthermore I am not getting any errors or warnings.
Load Component
Vue.component('topic', require('./components/Topicselect.vue'));
Use Component
<div class="form-group" id="topic">
<topic v-model="selectedTopic"></topic>
</div>
Initialise Vue
new Vue({
el: '#topic',
data: {
selectedTopic: null
}
});
Component
<template>
<div>
<label v-for="topic in topics" class="radio-inline radio-thumbnail" style="background-image: url('http://s3.hubsrv.com/trendsideas.com/profiles/74046767539/photo/3941785781469144249_690x460.jpg')">
<input type="radio" v-model="internalValue" :click="doSomething" name="topics_radio" :id="topic.id" :value="topic.name">
<span class="white-color lg-text font-regular text-center text-capitalize">{{ topic.name }}</span>
</label>
</div>
</template>
<script>
export default {
props: ['value'],
data () {
return {
internalValue: this.value,
topics: []
}
},
mounted(){
axios.get('/vuetopics').then(response => this.topics = response.data);
},
watch: {
internalValue(v){
this.$emit('input', v);
console.log('the value is ' + this.value);
}
},
methods: {
doSomething: function (){
console.log('doSomething is firing');
}
}
}
</script>
Full code: https://github.com/kenpeter/test_vue_simple_audio_2
In Main.vue
I tried to assign new value to this.player.currentTrack, by following this guide.
selectTrack: function selectTrack(id) {
this.player.currentTrack = Object.assign(
{},
this.player.currentTrack,
{ currentTrack: id },
);
this.player.elapsed = Object.assign(
{},
this.player.elapsed,
{ elapsed: 0 },
);
// this.play();
},
It seems no error, until I click the button
Error: Cannot read property 'duration' of undefined
In Main.vue, currentTrack.duration
<div class="player__timer">
<div class="player__timer__elapsed" v-text="player.elapsed"></div>
<div class="player__timer__total" v-text="currentTrack.duration"></div>
</div>
<div class="slider player__progress-bar">
<input type="range" :value="player.elapsed" :max="currentTrack.duration" />
</div>
From the image, you can see that there is a value: 274, which is the value of currentTrack.duration initially. After I click the button, currentTrack becomes undefined. currentTrack is a computed value.
You used currentTrack.duration instead of player.currentTrack.duration, try this:
<div class="player__timer">
<div class="player__timer__elapsed" v-text="player.elapsed"></div>
<div class="player__timer__total" v-text="player.currentTrack.duration"></div>
</div>
<div class="slider player__progress-bar">
<input type="range" :value="player.elapsed" :max="player.currentTrack.duration" />
</div>
this is the correct way to do object.assign. My method above is wrong.
let player = {
currentTrack: 0,
other: ""
};
console.log(player);
player = Object.assign(
{},
player,
{ currentTrack: 2}
);
console.log(player);
I'm currently trying to integrate spring mvc app using YUI3. I was able to call Spring Controller with static href in jsp through YUI, but script is not getting invoked when trying to invoke dynamically generated href.
<script src="http://yui.yahooapis.com/3.14.1/build/yui/yui-min.js"></script>
<script>
YUI().use('io-form', 'json','datatable','node','tabview',function(Y) {
Y.all('#nav a').on('click', function (ev) {
ev.preventDefault();
//main.load(ev.target.get('href'), '#content');
var href = ev.target.get('href');
var url = href.substring(0,href.indexOf('#'));
var idw = href.substring(href.indexOf('#')+1,href.length);
Y.io(url, {
method: 'GET',
on: {
complete: function(id, response) {
answer = Y.JSON.parse(response.responseText);
Y.log(answer);
var main = Y.one('#'+idw);
var node = main.all('li');
if(node.size()===0){
Y.Object.each(answer, function(item, index){
main.append("<li id='"+item+"' class='api-list-item class'><a href='/YUI-2-Spring/getContactDetails/"+item+".html#"+item+"'>"+item+"</a></li>");
});
}
}
}
});
});
//To call controller on clickin of dynamic links
Y.all('#api-Types a').on('click', function (ev) {
ev.preventDefault();
//main.load(ev.target.get('href'), '#content');
var href = ev.target.get('href');
var neturl = href.substring(0,href.indexOf('#'));
var studId= href.substring(href.indexOf('#')+1,href.length);
Y.io(neturl, {
method: 'GET',
on: {
complete: function(id, response) {
answer = Y.JSON.parse(response.responseText);
Y.log(answer);
var main = Y.one('#api-everything');
var node = main.all('li');
if(node.size()===0){
Y.Object.each(answer, function(item, index){
main.append("<li id='"+item+"' class='module-class'><a href='/YUI-2-Spring/getPersonalDetails/"+item+"/"+contId+"'</a>"+item+"</li>");
});
}
}
}
});
});
});
</script>
The first script I'm using for calling controller on tabview selection .Based on that I'm creating a list of String with href inside <ul id="api-Types" class="apis modules"></ul> field. In the next script, I'm trying to invoke the generated links, but script is not getting executed.
<div class="yui3-u-1-4">
<div id="docs-sidebar" class="sidebar apidocs">
<div id="api-list">
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="yui3-tabview-content">
<ul id="nav" class="tabs">
<li class="yui3-tab yui3-widget yui3-tab-selected">Elements</li>
<li class="yui3-tab yui3-widget">Contact Details</li>
<li class="yui3-tab yui3-widget">All</li>
</ul>
<div id="yui3-tabview-panel">
<ul id="api-elements" class="apis classes">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</ul>
<ul id="api-Types" class="apis modules">
<input type="search" id="api-filter" placeholder="Type to filter APIs"></ul>
<ul id="api-everything" class="apis search">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
<li class="message">
Begin typing in the search box above to see results.
</li>
</ul>
</div>
</div>
</div>
This is the dynamic list that got generated got from viewsource:
<ul id="api-Types" class="apis modules yui3-tab-panel yui3-tab-panel-selected" role="tabpanel" aria-labelledby="yui_3_14_1_1_1389513296688_62">
<input type="search" id="api-filter" placeholder="Type to filter APIs"><li class="api-list-item class">ABC</li><li id="BCD" class="api-list-item class">BCD</li><li id="CDE" class="api-list-item class">CDE</li><li id="DEF" class="api-list-item class">DEF</li><li id="EFG" class="api-list-item class">EFG</li><li id="FGH" class="api-list-item class">FGH</li></ul>
When I'm clicking on the links, instead of invoking the script, my controller is getting invoked through Dispatcher servlet.
Any help will be appreciated.
To bind events on dynamically added element on DOM you should use 'delegate' to bind event instead of 'on'. It will work.