ng-repeat shows only the last item from json - javascript

How can I display a specific number of items from JSON using ng-repeat. Right now its displaying only the last item.
JSON
{
"list":{
"item": {
"id":1,
"img": "1.jpg",
"user": "David Belle",
"text": "Cum sociis natoque penatibus et magnis dis parturient montes"
},
"item": {
"id":2,
"img": "2.jpg",
"user": "Jonathan Morris",
"text": "Nunc quis diam diamurabitur at dolor elementum, dictum turpis vel"
},
"item": {
"id":3,
"img": "3.jpg",
"user": "Fredric Mitchell Jr",
"text": "Phasellus a ante et est ornare accumsan at vel magnauis blandit turpis at augue ultricies"
}
}
}
ANGULARJS
Controller
app.controller('mainCtrl', ['$scope', '$resource', function($scope, $resource) {
$scope.msAPI = $resource("data/messages-notifications.json");
$scope.msResult = $scope.msAPI.get();
}]);
HTML
<div ng-controller="mainCtrl">
<a href="" ng-repeat="w in msResult.list">
<div class="lv-title">{{ w.user }}</div>
<small class="lv-small">{{ w.text }}</small>
</a>
</div>

The easiest way would be to change your JSON structure to include an array (instead of an object), as follows:
{
"list": [{
"id":1,
"img": "1.jpg",
"user": "David Belle",
"text": "Cum sociis natoque penatibus et magnis dis parturient montes"
}, {
"id":2,
"img": "2.jpg",
"user": "Jonathan Morris",
"text": "Nunc quis diam diamurabitur at dolor elementum, dictum turpis vel"
}, {
"id":3,
"img": "3.jpg",
"user": "Fredric Mitchell Jr",
"text": "Phasellus a ante et est ornare accumsan at vel magnauis blandit turpis at augue ultricies"
}]
}

Related

TINYMCE Editor External Templates: Uncaught TypeError: Cannot read property 'indexOf' of undefined

I am using TINYMCE Editor Version 4.8.2 (2018-08-09) and trying to add few prebuilt templates in .html in the list. I installed the template plugin in the plugin directory and initiated it in init-tinymce.js as below.
tinymce.init({
/* replace textarea having class .tinymce with tinymce editor */
selector: "textarea",
/* plugin */
plugins: [
"template"
],
/* toolbar */
toolbar: "template",
/* templates */
templates: [
{
title : "Default Template 1",
src : "tinymce-templates/template1.html",
description : "Default Template"
},
{
title : "Default Template 2",
src : "tinymce-templates/template2.html",
description : "Default Template"
}
]
});
Now when I try to open and insert my added templates then I am able to see my both template in the dropdown list but when I cant see the preview. On inspecting, I found this error shared below.
Uncaught TypeError: Cannot read property 'indexOf' of undefined plugin.min.js:1
at S (plugin.min.js:1)
at i.onselect (plugin.min.js:1)
at Vg.c.fire (tinymce.min.js:2)
at i.fire (theme.min.js:1)
at w (plugin.min.js:1)
at plugin.min.js:1
at i.<anonymous> (plugin.min.js:1)
at Vg.c.fire (tinymce.min.js:2)
at i.fire (theme.min.js:1)
at HTMLDivElement.o (theme.min.js:1)
S # plugin.min.js:1
onselect # plugin.min.js:1
Vg.c.fire # tinymce.min.js:2
fire # theme.min.js:1
w # plugin.min.js:1
(anonymous) # plugin.min.js:1
(anonymous) # plugin.min.js:1
Vg.c.fire # tinymce.min.js:2
fire # theme.min.js:1
o # theme.min.js:1
C # tinymce.min.js:2
d
And my template is like something below...
<div class="mceTmpl">
<div class="row">
<div class="box">
<div class="col-lg-12">
<hr>
<h2 class="intro-text text-center">Build a website
<strong>worth visiting</strong>
</h2>
<hr>
<hr class="visible-xs">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc placerat diam quis nisl vestibulum dignissim. In hac habitasse platea dictumst. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
</div>
</div>
</div>
I believe where you have a src attribute the correct attribute is url. Per the documentation I see this:
This option lets you specify a predefined list of templates to be
inserted by the user into the editable area. It is structured as an
array with each item having a title, description and content/url.

How do I update blog post in Mongoose?

I am building a blog site using CRUD operations. I can create, read and delete but I am having hard time with updating a created post.
Basically I have it where I can click on the "edit" button on an individual entry in home.ejs and into the edit.ejs route where that input fields are populated with current title and content. But what I can not figure out is clicking "Publish" in edit.ejs to update its own post.ejs title and content. When it is done, I want to redirect it back to the main page. Down on the "app.post("/edit/:id")" route, am I supposed to use "PUT" request to update the post?
I am sorry if this is tough to follow. I am not very good at explaining things.
Here's the relevant code:
app.js
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const _ = require("lodash");
const aboutContent = "Hac habitasse platea dictumst vestibulum rhoncus est pellentesque. Dictumst vestibulum rhoncus est pellentesque elit ullamcorper. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit. Egestas sed sed risus pretium quam vulputate dignissim suspendisse. Mauris in aliquam sem fringilla. Semper risus in hendrerit gravida rutrum quisque non tellus orci. Amet massa vitae tortor condimentum lacinia quis vel eros. Enim ut tellus elementum sagittis vitae. Mauris ultrices eros in cursus turpis massa tincidunt dui.";
const contactContent = "Scelerisque eleifend donec pretium vulputate sapien. Rhoncus urna neque viverra justo nec ultrices. Arcu dui vivamus arcu felis bibendum. Consectetur adipiscing elit duis tristique. Risus viverra adipiscing at in tellus integer feugiat. Sapien nec sagittis aliquam malesuada bibendum arcu vitae. Consequat interdum varius sit amet mattis. Iaculis nunc sed augue lacus. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. Pulvinar elementum integer enim neque. Ultrices gravida dictum fusce ut placerat orci nulla. Mauris in aliquam sem fringilla ut morbi tincidunt. Tortor posuere ac ut consequat semper viverra nam libero.";
let app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
mongoose.connect("mongodb://localhost:27017/blogDB", {
useNewUrlParser: true
});
const postSchema = {
date: String,
title: String,
content: String
}
const Post = mongoose.model("Post", postSchema);
app.get("/", (req, res) => {
Post.find({}, (err, posts) => {
res.render("home", {
posts: posts
});
});
});
app.get("/about", (req, res) => {
res.render("about", {
aboutContent: aboutContent
});
});
app.get("/contact", (req, res) => {
res.render("contact", {
contactContent: contactContent
});
});
app.get("/compose", (req, res) => {
res.render("compose");
});
app.post("/compose", (req, res) => {
const postTitle = req.body.postTitle;
const postBody = req.body.postBody;
let date = new Date();
let postDate = date.toLocaleString('en-US');
const post = new Post({
date: postDate,
title: postTitle,
content: postBody
});
post.save(err => {
if (!err) {
res.redirect("/");
}
});
});
app.get("/edit/:id", (req, res) => {
const requestedId = req.params.id;
console.log(req.body);
Post.findOne({
_id: requestedId
}, (err, post) => {
if (!err) {
res.render("edit", {
title: post.title,
content: post.content
});
}
});
});
app.post("/edit/:id", (req, res) => {
const requestedId = req.params.id;
console.log(req.body);
Post.findOne({
_id: requestedId
}, (err, post) => {
if (!err) {
res.render("edit", {
title: post.title,
content: post.content
});
}
});
});
app.get("/posts/:id", (req, res) => {
const requestedId = req.params.id;
Post.findOne({
_id: requestedId
}, (err, post) => {
if (!err) {
res.render("post", {
title: post.title,
content: post.content
});
}
});
});
app.post("/delete", (req, res) => {
const deletePost = req.body.delete;
Post.findByIdAndDelete(deletePost, (err) => {
if (!err) {
res.redirect("/");
}
});
});
app.listen(3000, function () {
console.log("Server started on port 3000");
});
home.ejs
<%- include("partials/header") -%>
<h1>Home</h1>
<button type="button" class="new-entry btn btn-dark">New Entry</button>
<div class="entries-container">
<% posts.forEach(post => { %>
<div class="blog-entry">
<p class="post-date">Posted on
<%= post.date %>
</p>
<h2>
<%= post.title %>
</h2>
<div class="entry-footer">
<button type="button" class="btn btn-outline-primary">VIEW</button>
<form action="/edit" method="POST">
EDIT</button>
</form>
<form action="/delete" method="POST">
<button type="submit" name="delete" value="<%= post._id %>" class="btn btn-outline-danger">DELETE</button>
</form>
</div>
</div>
<% }) %>
</div>
<%- include("partials/footer") -%>
edit.ejs
<%- include("partials/header") -%>
<h1>Compose</h1>
<form action="/edit" method="PUT">
<div class="form-group">
<label for="postTitle">Title</label>
<input type="text" name="postTitle" class="form-control" id="postTitle" autocomplete="off" value="<%= title %>">
<label for="postBody">Post</label>
<textarea name="postBody" class="form-control" autocomplete="off" rows="8"><%= content %></textarea>
</div>
<button type="submit" name="button" class="btn btn-primary">Publish</button>
</form>
<%- include("partials/footer") -%>
post.ejs
<%- include("partials/header") -%>
<h2 class="post-title"><%= title %></h2>
<p class="post-content"><%= content %></p>
<%- include("partials/footer") -%>
If you want to simply update your existing blog post title and content with sending POST request then you can do it with findOneAndUpdate() as below:
app.post("/edit/:id", (req, res) => {
const requestedId = req.params.id;
console.log(req.body);
Post.findOneAndUpdate({
_id: requestedId // Query Part
},
{
$set: {
title: req.body.title, // Fields which we need to update
content: req.body.content
}
},
{
new: true // option part ( new: true will provide you updated data in response )
},(err, post) => {
if (!err) {
res.render("edit", {
title: post.title,
content: post.content
});
}
});
});

Angularjs - UI Boostrap: Accordion Open and close all

i have written some code to open and close all tabs of an accordion respectively use a separate 'open' and 'close' button. How ever it requires me to dynamically add a key value pair(a Boolean value) to my json data.
What is the best practice in this situation? should i add the Boolean value as a static json element or is it OK to dynamically add values when their sole purpose is for visual structure and not relevant to actual object data.
HTML/Angular directives
<div id="app" ng-app="demoApp">
<div id="controller" ng-controller="demoAppCtrl">
<uib-accordion close-others="false">
<div class="btn-group form-group">
<button type="button" class="btn btn-warning" ng-click="toggle(true)">Open</button>
<button type="button" class="btn btn-warning" ng-click="toggle(false)">Close</button>
</div>
<uib-accordion-group is-open="hero.state" ng-click="setOpened(false)" ng-repeat="hero in heroes">
<uib-accordion-heading>
{{hero.name}}
</uib-accordion-heading>
{{hero.bio}}
</uib-accordion-group>
</uib-accordion>
</div>
</div>
Javascript/Angular
var app = angular.module('demoApp', ['ngAnimate','ui.bootstrap']);
app.controller('demoAppCtrl', function($scope) {
// This json object contain only one entry as an example
$scope.heroes = [
{'name': 'Captain America', 'team': 'Avengers', 'bio': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae metus placerat, condimentum nisl et, accumsan sapien. Quisque molestie magna nulla, id malesuada sem interdum a.'}
];
$scope.addDefaultState = function(val) {
for (var i=0;i<$scope.heroes.length;i++) {
$scope.heroes[i].state = val;
}
}
$scope.addDefaultState(false);
$scope.toggle = function(status) {
$scope.heroes.forEach(function(e) {
e.state = status;
});
}
});
codepen.io - Working example (with corrections)
In my opinion the static json should not contain Boolean state value. It is okay to dynamically add values for visual presentation.
In your code the function addDefaultState is not needed. The is-open="hero.state" will take care of default state cause initially it will not find state and will consider it as false. So you change your code like below it should work too:
var app = angular.module('demoApp', ['ngAnimate','ui.bootstrap']);
app.controller('demoAppCtrl', function($scope) {
// This json object contain only one entry as an example
$scope.heroes = [
{'name': 'Captain America', 'team': 'Avengers', 'bio': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae metus placerat, condimentum nisl et, accumsan sapien.'}
];
$scope.toggle = function(status) {
$scope.heroes.forEach(function(e) {
e.state = status;
});
}
});

Ionic app - controller $http

I am building a app in ionic, i am trying to get external restful api data into the view via a controller, but there seems to be something wrong with my controller because nothing is being pulled in?
my code is:
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('myCtrl', function($scope, $http) {
$http.get('http://jsonplaceholder.typicode.com/posts').then(function(results){
$scope.posts = results.data.posts;
}, function(err) {
console.error('ERR', err);
// err.status will contain the status code
})
});
<ion-content class="has-subheader" ng-controller="myCtrl">
<ion-list>
<ion-item ng-repeat='item in posts' class="item-thumbnail-left item-text-wrap">
<img src="http://placehold.it/100x100" alt="photo">
<h2>{{post.title}}</h2>
<h4>Place</h4>
<p style="font-size:12px; line-height:16px;">Quisque quis sem a velit placerat vehicula quis nec felis. Mauris posuere, nisl vitae condimentum luctus, tellus enim blandit orci, quis efficitur nibh libero eget dui. Aliquam fermentum velit quis sem molestie.</p>
</ion-item>
</ion-list>
</ion-content>
Any help would be appreciated.
Solution to this:
$http.get('http://jsonplaceholder.typicode.com/posts')
.success(function(results){
$scope.posts = results.posts;
console.log($scope.posts);
});
You were using data but there isn't data in the results. Look at the console, and you should see objects now.
Working codepen
you have made 2 mistakes in your code:
First: once you define 'item' in ng-repeat you should use it to bind your object key "title":
ng-repeat='item in posts'
'item' is now holding your JSON keys.
<h2>{{item.title}}</h2>
Second: reviewing jsonplaceholder JSON you are calling through this url, http://jsonplaceholder.typicode.com/posts, title key is under results.data
, so you should define posts like this:
$scope.posts = results.data
For more help: I've taken the code you provided and made it working on a plunk, check it on the following url:
http://embed.plnkr.co/Gp1U3y/preview
Please contact me for more help. Thanks

How to create a custom <select> filter in Angular.js using 2 JSON options

I have a Q&A JSON feed with the following:
"questions": [
{
"answer": "Ea et non sunt dolore nulla commodo esse laborum ipsum minim non.",
"id": 0,
"poster": "Chelsea Vang",
"question": "Ex ex elit cupidatat ullamco labore quis cupidatat. Reprehenderit occaecat mollit ex proident aliqua. Anim minim in labore pariatur adipisicing velit dolore elit nostrud proident reprehenderit in voluptate.",
"userAsked": false
},
{
"answer": null,
"id": 1,
"poster": "Serena Randolph",
"question": "Esse occaecat anim cupidatat eu sit ad eiusmod. Et tempor deserunt ea ipsum velit irure elit qui. Ipsum qui labore laboris Lorem occaecat enim Lorem exercitation ut non duis. Sit cillum incididunt culpa ipsum.",
"userAsked": true
}
]
I want to create a custom filter that allows you to filter (by select dropdown) the results by: All Questions, "userAsked: true" a.k.a My Questions, and Answered Questions (so questions that are not 'null' in this case it would be something like !null?). I know how to create a custom filter for a single object, but can't figure out how to do it in this instance since I am trying to filter by more then one option-I can't do an ng-repeat for the select options because of this.. unless I am under the wrong impression.
My view looks something like this:
<select>
<option value="all">All Questions</option>
<option value="answered">Answered Questions</option>
<option value="mine">My Questions</option>
</select>
<ul class="list-unstyled">
<li ng-repeat="questions in qa.questions">
<strong>Question:</strong><br>
{{questions.question}}<br>
<strong>Answer:</strong><br>
{{questions.answer}}
<hr>
</li>
</ul>
Controller:
sessionControllers.controller('SessionDetailCtrl', ['$scope', '$routeParams', 'SessionFactory', 'CommentsFactory', 'QAFactory', function($scope, $routeParams, SessionFactory, CommentsFactory, QAFactory){
$scope.session = SessionFactory.get({id: $routeParams.id});
$scope.comments = CommentsFactory.get({eventId: $routeParams.id});
$scope.qa = QAFactory.get({eventId: $routeParams.id});
}]);
Please help! Thank you :)
I was able to figure it out by implementing some of what #tymeJV suggested.
View
<select ng-model="filterItem.question" ng-options="item.questionType for item in filterOptions.questions">
<option value="All Questions">All Questions</option>
<option value="Answered Questions">Answered Questions</option>
<option value="My Questions">My Questions</option>
</select>
<ul>
<li ng-repeat="questions in qa.questions | filter: myCustomFilter">
<strong>Question:</strong>
<br>{{questions.question}}<br>
<strong>Answer:</strong><br>
{{questions.answer}}
</li>
</ul>
Controller
$scope.filterOptions = {
questions: [
{questionType: 'All Questions'},
{questionType: 'Answered Questions'},
{questionType: 'My Questions'}
]
};
//Mapped to the model to filter
$scope.filterItem = {
question: $scope.filterOptions.questions[0]
};
//Custom filter - filter based on the QuestionType selected
$scope.myCustomFilter = function (data) {
if ($scope.filterItem.question.questionType === "All Questions") {
return true;
} else if ($scope.filterItem.question.questionType === 'Answered Questions') {
return data.answer != null;
} else if ($scope.filterItem.question.questionType === 'My Questions') {
return data.userAsked;
}
};
Hmm, attach a model to your select filter and try something like this:
<select ng-model="questionFilter">
<option value="all">All Questions</option>
<option value="answered">Answered Questions</option>
<option value="mine">My Questions</option>
</select>
<li ng-repeat="questions in qa.questions | filter: myCustomFilter">
And the controller:
$scope.myCustomFilter = function(item) {
if (questionFilter == "all") {
return true;
} else if (questionFilter == "answered") {
return item.answer != null;
} else if (questionFilter == "mine")
return item.userAsked;
}

Categories

Resources