Get single post id from json file in AngularJS - javascript

This is maybe real easy, don´t know. But i´ve only done this with a node/express backend.
But not quite surt how to do this, only with frontend and a json file, where my data is.
Right now it shows a list of all my posts, but i want to get the unique post:id when clicking on a button.
A simple posts.json file:
[{
id: 1,
title: 'Simple title1',
content: 'Sample content...',
permalink: 'simple-title1',
author: 'Peter',
datePublished: '2012-04-04'
}, {
id: 2,
title: 'Simple title2',
content: 'Sample content...',
permalink: 'simple-title2',
author: 'Peter',
datePublished: '2012-05-04'
}, {
id: 3,
title: 'Simple title3',
content: 'Sample content...',
permalink: 'simple-title3',
author: 'Thomas',
datePublished: '2012-06-04'
}]
Here is my app.js file:
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/posts',
templateUrl: 'partial-home.html',
controller: function($scope, $http){
$http.get('posts.json')
.success(function(data){
$scope.posts = data;
});
}
})
.state('viewdetails',{
url:'/posts/:id/:permalink',
templateUrl: 'view_details.html',
controller: function($scope, $http){
$http.get('source.json')
//get a single post here???
} }
And some of the code in my partial-home.html
<div class="row" style="margin-left:50px">
<!--row left-->
<div class="col-xs-8 col-sm-4 col-md-3 col-lg-5 box-background" ng-repeat="post in posts">
<!--column 1 left-->
<div class="col-md-4 img-space">
<img class="img-circle" alt="Bootstrap Image Preview" src="{{prov.picture}}" /></div>
<div class="col-md-4">
<h4>{{post.author}}</h4>
<p class="text-grey">
{{post.content}}
</p>
</div>
<a ui-sref="posts/:id" class="btn btn-primary btn-color" style="width:100%">View details</a>
</div>
<!--end column 1 left-->
</div>
<!--end row left-->
I know this isn´t in a mvc pattern, but just want to do it really simple.
Have only done this before with a mongoose, node backend. So hope for some ideas help.
Thanks.

You would use $routeParams to get the id from your route and then use that as a variable in your $http request url.
When fetching the same sourse.json file you can use that id to only assign the correct post to your view variable
https://docs.angularjs.org/api/ngRoute/service/$routeParams

Related

AngularJS expression doesn't work in a different view

So I have this problem with creating a new view. The routeing works just fine because it shows the required HTML perfectly, but the expressions which worked just fine in the main view don't show up in the new.
<a href="#/view/{{todo.id}}" id="super" ng-repeat="todo in todos | filter: search">
<div id="main" ng-class="{'done': todo.done}">
<input type="checkbox" ng-model="todo.done" />
<span>{{todo.title}}</span>
<button id="info">i</button>
<div class="inf">
<span>Prioritás: {{todo.priority}}</span>
</div>
<div class="inf" id="sec">
<span>Határidő: {{todo.deadLine | date: "yyyy. MMMM. dd"}}</span>
</div>
</div>
</a>
These are the expressions in the main view, they work like a charm.
myTodoList.config(['$routeProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('', {
templateUrl: 'index.html',
controller: "mainController"
})
.when('/view/:id', {
templateUrl: 'view.html',
controller: "mainController"
}).otherwise({
redirectTo: ''
});
This is the routeing part, this is working.
<div id="mainContent">Master Detail
<div ng-controller="mainController" ng-view></div>
</div>
This is the div where the new view goes.
<div>
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p></div>
And this is the view.html. The third expression is working, so I have the problem with de other two expressions. I think I messed up this because I can't reach the data I want. todo.id and todo.title are data created by a function in real time.
$scope.addTodo = function(title, priority, deadLine, id) {
$scope.todos.push({
'id': lastId,
'title': $scope.newTodo,
'done': false,
'priority': $scope.newPriority,
'deadLine': $scope.newDeadLine
});
$scope.newTodo = ''
$scope.newPriority = ''
$scope.newDeadLine = ''
lastId++;
}
This is the function I am using. I hope I described the problem well.
Are you using ng-repeat in your new view ?
<div>
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p></div>
Your Scope variable name is $socpe.todos but here you are trying to access todo make sure if you are inside the ng-repeat if this is not your problem then share your full code on fiddle or codepen.
Just like Jeyenthaaran Nanjappan said, i think your div should look like this:
<div ng-repeat="todo in todos">
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p>
</div>
Okay, I solved the problem. I needed to separate the different objects. So I made a function.
$scope.currentTodo = $scope.todos[0];
$scope.selectTodo = function(todo) {
$scope.currentTodo = todo;
}
I made a div and called this function with it.
<div ng-click="selectTodo(todo);" id="super" ng-repeat="todo in todos | filter: search">
And the problematic div now looks like this.
<div id="mainContent">Master Detail
<div>
<p>Should be the ID: {{currentTodo.id}}</p>
<p> should be the title: {{currentTodo.title}}</p>
</div>
</div>
Thank you for your help! I think both of you helped me through this problem.
Some issues in the nesting of the div and html. Change this:
<div id="mainContent">Master Detail
<div ng-repeat="todo in todos" ng-controller="mainController" ng-view></div>
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p>
</div>
to this:
<div id="mainContent">Master Detail
<div ng-repeat="todo in todos" ng-controller="mainController">
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p>
</div>
</div>

MEANStack tutorial on thinkster, route parameter doens't work

I'm following a MEAN tutorial on Thinkster (https://thinkster.io/mean-stack-tutorial) and can't find a sollution for passing the route parameter.
My problem comes from this section in the tutorial (https://thinkster.io/mean-stack-tutorial#the-posts-page)
When I want to see the comments of a post (by passing the route parameter in my URL). The tutorial says :
For now, we will consider the index of the post to be its id. We can use $stateParams to retrieve the id from the URL and load the appropriate post.
Using the folowing code :
$scope.post = posts.posts[$stateParams.id];
<span>
Comments
</span>
I have no idea what I'm doing wrong. But I don't think my code runs through the PostCtrl controller.
Anyone knows what I'm doing wrong?`
<html>
<head>
<title>Flapper News</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="app.js"></script>
<style>
.glyphicon-thumbs-up {
cursor: pointer
}
</style>
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
<!-- Waar de template moet geplaatst worden in actieve state !-->
</div>
</div>
<!-- Home state !-->
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></span> {{post.upvotes}}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()" style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Title" ng-model="title"></input>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Link" ng-model="link"></input>
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
<!-- Posts state !-->
</script>
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
<div ng-repeat="comment in post.comment | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">
{{comment.body}}
</span>
</div>
</script>
<!-- Andere state !-->
</body>
</html>
var app = angular.module('flapperNews', ['ui.router']);
app.config([
'$stateProvider',
'$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl'
});
$stateProvider.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});
$urlRouterProvider.otherwise('home');
}
]);
/* We creeeren een nieuw object dat een property posts heeft.
We geven dan die variabele (o) terug zodat deze door elke angular module kan gebruikt worden.
Je kan hier ook methode in exporteren
$scope.posts = posts.posts in MainCtrl --> Nu wordt elke wijziging opgeslaan in de service*/
app.factory('posts', [function () {
var o = {
posts: []
};
return o;
}]);
app.controller('MainCtrl', [
'$scope', 'posts',
function ($scope, posts) {
$scope.posts = posts.posts
$scope.posts = [{
title: 'post 1',
upvotes: 5
}, {
title: 'post 2',
upvotes: 2
}, {
title: 'post 3',
upvotes: 15
}, {
title: 'post 4',
upvotes: 9
}, {
title: 'post 5',
upvotes: 4
}];
$scope.addPost = function () {
if (!$scope.title || $scope.title === '') {
return;
}
$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0,
comments: [{
author: 'Joe',
body: 'Cool post!',
upvotes: 0
}, {
author: 'Bob',
body: 'Great idea but everything is wrong!',
upvotes: 0
}]
});
$scope.title = '';
$scope.link = '';
};
$scope.incrementUpvotes = function (post) {
post.upvotes += 1;
};
}
]);
app.controller('PostsCtrl', [
'$scope',
'$stateParams',
'posts',
'post',
function ($scope, $stateParams, posts, post) {
$scope.post = posts.posts[$stateParams.id];
}
]);
You have re-declared $scope.posts in your MainCtrl, so changes in MainCtrl are never being reflected in your posts factory.
The problem is at:
$scope.posts = posts.posts;
$scope.posts = [{
title: 'post 1',
upvotes: 5
}, {
title: 'post 2',
upvotes: 2
}, {
title: 'post 3',
upvotes: 15
}, {
title: 'post 4',
upvotes: 9
}, {
title: 'post 5',
upvotes: 4
}];
The first statement is setting $scope.posts equal to your factory object, the second is setting it to a local array.
You should instead use push to add your data into the factory array.
$scope.posts = posts.posts;
$scope.posts.push({
title: 'post 1',
upvotes: 5
}, {
title: 'post 2',
upvotes: 2
}, {
title: 'post 3',
upvotes: 15
}, {
title: 'post 4',
upvotes: 9
}, {
title: 'post 5',
upvotes: 4
});​
Also, you have an extra injection in your PostsCtrl, there is no post service to be injected.
A full working copy of your code with relevant changes is on plnkr.

Trouble with ng-repeat

I'm trying to get to grips with AngularJS and had this working to echo individual things from a controller, but when I tried to incorporate a loop with ng-repeat all I get is {{tasks.title}} flashing onscreen for a second, then a blank empty div.
Any examples I've looked up seem a little different and I've tried a few ways, can anyone see where I'm going wrong?
Controller:
app.controller('MainController', ['$scope', function($scope) {
$scope.tasklist = {
tasks: [{
title: 'Wash Dog'
}, {
title: 'Email Joe'
}]};
}
]);
HTML:
<section class="panel">
<div ng-controller="MainController">
<div class="thumbnail" ng-repeat="tasks in tasklist">
<p>{{ tasks.title }}</p>
</div>
</div>
</section>
You are accessing the property tasklist not the actual tasks. It should be tasklist.tasks
<section class="panel">
<div ng-controller="MainController">
<div class="thumbnail" ng-repeat="tasks in tasklist.tasks">
<p>{{ tasks.title }}</p>
</div>
</div>
</section>
Another way would be to remove the tasks property:
app.controller('MainController', ['$scope', function($scope) {
$scope.tasklist = [
{
title: 'Wash Dog'
},
{
title: 'Email Joe'
}
];
}]);

Accessing the 'id' value from the side menu example from the Iconic framework using AngularJS and

With the Iconic Framework side menu example how do I access the 'id' and 'Title' value from the controller?
.controller('PlaylistsCtrl', function($scope) {$scope.playlists = [
{ title: 'Traffic', id: 1 },
{ title: 'Litter', id: 2 },
{ title: 'Marine', id: 3 }]
In the Playlist.html template file?
<ion-view view-title="Playlist One">
<ion-content>
<h1>Playlist</h1>
</ion-content>
</ion-view>
The other relevant code from app.js file is:
.state('app.single', {
url: "/playlists/:playlistId",
views: {
'menuContent': {
templateUrl: "templates/playlist.html",
controller: 'PlaylistCtrl'
}
}
})
And the controller - I think:
.controller('PlaylistCtrl', function($scope) {
})
Old Ans
Its Simple. you just have to insure that in your Config you have assigned controller to the view.
<ion-view view-title="Playlist One">
<ion-content>
<h1>Playlist</h1>
<ul>
<li ng-repeat="p in playlists">
ID: {{p.id}}
</li>
</ul>
</ion-content>
</ion-view>
Updated
<ion-view view-title="Playlist One">
<ion-content>
<h1>Playlist</h1>
<!-- Pass playlist as a parameter named **p** here onclick function-->
<ul>
<li ng-repeat="p in playlists" ng-click="selected(p)">
ID: {{p.id}}
</li>
</ul>
</ion-content>
</ion-view>
Your controller will look like this.Only you need to add selected function in your controller like this.
.controller('PlaylistCtrl', function($scope) {
$scope.selected=function(playlist){
$scope.selectedPlaylist=playlist;
console.log($scope.selectedPlaylist.id)
}
})
You should bind PlaylistsCtrl to this ion-view from its state mentioned in config phase.
<ion-view view-title="Playlist One">
<ion-content>
<h1>Playlist</h1>
<div ng-repeat="playlist in playlists">
Number: {{playlist.id}} | Title: {{playlist.title}}
</div>
</ion-content>
</ion-view>

$state.go don't work in ionic framework

I'm creating a cordova app with ionic framework, i created a blank app with CLI, in my index.html i have a slide box, in which i have a button in the last slide.
I have registered a click event in that button, in click in the button i would like to navigate to templates/projects.html.
I hope my problem is clear.
Thanks
index.html file
<body ng-app="starter" class="platform-android platform-cordova platform-webview">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">BabyLapse</h1>
</ion-header-bar>
<ion-content>
<ion-slide-box style="height:100%" on-slide-changed="slideHasChanged($index)">
<ion-slide >
<div style="height:100%" class="box blue"><h1>BLUE</h1>
<img src="img/tutorial_img1.jpg">
</div>
</ion-slide>
<ion-slide>
<div class="box yellow"><h1>YELLOW</h1>
<img src="img/tutorial_img2.jpg">
</div>
</ion-slide>
<ion-slide>
<div class="box pink"><h1>PINK</h1>
<img src="img/tutorial_img3.jpg" class="image">
</div>
</ion-slide>
<ion-slide>
<div class="box blue"><h1>BLUE</h1>
<img src="img/tutorial_img4.jpg">
</div>
</ion-slide>
<ion-slide ng-controller="FirstSlideCtrl">
<div class="box yellow"><h1>YELLOW</h1>
<!-- <img src="img/tutorial_img5.jpg" >-->
<button style="z-index:1000;height:100px;width:100px" ng-click="go('app.projects');">Créer Projet</button>
</div>
</ion-slide>
</ion-slide-box>
</ion-content>
</ion-pane>
app.js file
angular.module('starter', ['ionic', 'starter.controllers', 'ngCordova'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "index.html",
controller: 'StarterCtrl'
})
.state('app.projects', {
url: "/projects",
views: {
'projects': {
templateUrl: "templates/projects.html",
controller: 'ProjectsCtrl'
}
}
});
//$urlRouterProvider.otherwise('/projects');
})
.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();
}
})
});
controllers.js
angular.module('starter.controllers', ['ui.router'])
.controller("StarterCtrl", function($scope) {
$scope.data = {
numViewableSlides: 0,
slideIndex: 0,
initialInstruction: true,
secondInstruction: false
};
$scope.slideHasChanged = function(index) {
$scope.data.slideIndex = index;
};
$scope.go = function(route) {
alert('1');
$state.go(route);
};
})
.controller("ProjectsCtrl", function($scope) {
$scope.playlists = [{
title: 'Reggae',
id: 1
}, {
title: 'Chill',
id: 2
}, {
title: 'Dubstep',
id: 3
}, {
title: 'Indie',
id: 4
}, {
title: 'Rap',
id: 5
}, {
title: 'Cowbell',
id: 6
}];
})
.controller("FirstSlideCtrl", function($scope, $state) {
$scope.go = function(route) {
alert(route);
$state.go('app.projects');
};
});
I cannot follow your code so I'll try to recreate.
In Ionic/Cordova you should have an index.html which would be your entry for the application.
This is the place where you bind your HTML with the angular app and where your reference your scripts.
It should have a body with the main nav-view <ion-nav-view>:
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
My ng-app is called app but you can easily replace it with starter.
Then you would have separate "pages" for different views. I can imagine in your situation you would have one view for the slider and the second one for the project's creation.
Each view must be defined in a <ion-view> where you're going to a have a content <ion-content>.
I imagine you're going to need to states:
.state('main', {
url: '/main',
templateUrl: 'main.html',
controller: 'mainController',
})
.state('projects', {
url: '/projects',
templateUrl: 'projects.html',
controller: 'projectsController',
});
if you want to go to projects from the slider page you simply have to:
$state.go('projects')
This is the end result in a plunker.
As you can see I got read of the abstract view cause it seems to me that you don't really need it as you're not using any base template: side-menu or tabs.
You can always add it but your abstract should never refer the index.html file.

Categories