retrieve the data from json folder with angularjs - javascript

Hello I try to make a angularjs application so i retrieve a data from a json folder but it's display lik this ["adventure","sci-fi"]
how can I please remove [" "] from this ["adventure","sci-fi"]
this is my json folder
[
{
"title": "Interstellar",
"genre": [
"adventure",
"sci-fi"
],
"watched": false
},
{
"title": "Inception",
"genre": [
"action",
"mystery",
"sci-fi"
],
"watched": true
}
]
and this my service.js
var app = angular.module('appMovies', [] );
app.service('moviesService', function($http,$q){
var deferred =$q.defer();
$http.get('movies.json').then(function (data)
{
deferred.resolve(data);
});
this.getPlayers = function ()
{
return deferred.promise;
}
})
and this my controller
app.controller('appcontrolles', function($scope,moviesService){
var promise = moviesService.getPlayers();
promise.then(function(data)
{
$scope.players =data.data;
console.log($scope.players);
});
})
and this is my index.html
<table class="table table-striped">
<thead>
<tr>
<th>title</th>
<th>genre</th>
<th>watched</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="movie in players | filter : genre |filter: search.genre |filter : watched ">
<td>{{movie.title}}</td>
<td>{{movie.genre}}</td>
<td><input type="checkbox" name="vu", ng-model="movie.watched",value="true"></td>
</tr>
</tbody>
</table>
thanks for your help

Since movie.genre is an array, when you just put {{movie.genre}}, Angular outputs the value as a string representing an array: ["adventure","sci-fi"].
If you want a simple comma-delimited list of values, you could use the .join() function of an array to create a string with a specify delimiter, like ", ", like so:
<td>{{movie.genre.join(", ")}}</td>
Alternatively, if you want more complex DOM around it, then you could ng-repeat over that array:
<td><span ng-repeat="genre in movie.genre">{{genre}}</span></td>
Off Topic:
You don't need to use $q.defer with something that already returns a promise, like $http - you can just return that promise, and so your service could be simplified to:
app.service('moviesService', function($http){
this.getPlayers = function()
{
return $http.get('movies.json');
}
});
$q.defer is used when you are trying to convert a non-promise async function of some third-party service, for example, which uses on-success and on-error handlers.

Related

Trying to display a table with data from API, array inside JSON Object ANGULAR

I'm working in a project to help a friend, so most of the code in the services and the backend was already there, so I've been struggling with the structure and sometimes I get lost.
Here's my problem
This is the structure of the data on the API:
{
"title": "",
"iconURL": ",
"linkedRightsIDs": [
""
],
"linkedRights": [
{
"id": ,
"creationDate": "",
"sections": [
"women"
],
"defLanguage": "en",
"countryApplied": "united states",
"statesApplied": [
"all"
],
"title": "",
"translations": [
"en"
],
"disable": false,
"content": null
}
]
}
What I'm trying to achieve, is to make a table inside my component using the LinkedRights data. Right now, this structure only have 1 linkedRight (I deleted the data inside for privacy)
Anyways, here's the method regarding the service and model in my component.ts:
onModelLoadedAsync() {
super.onModelLoadedAsync();
if (this.mode == 'create') {
this.model = LocalityInfo;
} else {
if (this.model.iconURL){
this.imageSrc = this.model.iconURL;
}
}
if(this.mode == 'edit'){
const data= Object.entries(this.model.linkedRights); //this is me just testing
console.log(data);
}
}
here's the html of the table I'm trying to display, this is and edit route so there's a query param for the id in this view
<div class="table-responsive">
<table class="table table-hover">
<thead class="thead-dark">
<tr>
<th>Title</th>
<th>Sections</th>
<th>States</th>
<th>Enabled</th>
<th>Creation Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of data">
<td>{{item.title}}</td>
<td>{{item.sections}}</td>
<td>{{item.statesApplied}}</td>
<td>{{!item.disabled}}</td>
<td>{{item.creationDate}}</td>
</tr>
</tbody>
</table>
</div>
</div>
What I was trying to do, was to convert the JSON into an array so I could display it since there's an error that shows on the console that said this:
core.js:6456 ERROR Error: Cannot find a differ supporting object '[object Object]' of type'object'. NgFor only supports binding to Iterables such as Arrays.

Accessing nested JSON data in React Component

Hi i am just starting to learn react as a side project.
Im using an express backend to call an api that returns some JSON to my component. I cant seem to access the nested array to iterate over and display.
import React, { Component } from 'react';
import '../../app.css';
export class Table extends Component {
constructor(props) {
super(props);
this.state = {
jsonItems: [],
isLoaded: false
}
}
componentWillMount() {
this.renderMyData();
}
renderMyData() {
fetch('/api/nfl')
.then(res => res.json())
.then(json => {
this.setState({
jsonItems: JSON.parse(json),
isLoaded: true
})
})
}
render() {
console.log(this.state.jsonItems.fullgameschedule);
return (
<table>
<thead>
<tr>
<th>Test 1</th>
<th>Test 2</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
)
}
}
Json output:
{
"fullgameschedule": {
"lastUpdatedOn": "2018-08-24 2:55:41 PM",
"gameentry": [
{
"id": "43306",
"week": "1",
"scheduleStatus": "Normal",
"originalDate": null,
"originalTime": null,
"delayedOrPostponedReason": null,
"date": "2017-09-07",
"time": "8:30PM",
"awayTeam": {
"ID": "73",
"City": "Kansas City",
"Name": "Chiefs",
"Abbreviation": "KC"
},
"homeTeam": {
"ID": "50",
"City": "New England",
"Name": "Patriots",
"Abbreviation": "NE"
},
"location": "Gillette Stadium"
}
]
}
}
jsonItems gets populated (as shown in my react dev tools). but i cant seem to iterate over the json array "gameentry"
I can print out {this.state.jsonItems.fullgameschedule} , but i cant access it any further for example {this.state.jsonItems.fullgameschedule.gameentry} or gameentry[0] without the error message:
Cannot read property 'gameentry' of undefined
Which at first i thought was because of js being asynchronous that it was loading the component before it rendered, so i changed componentDidMount() to componentWillMount() and that should handle that. How can i access the array list and iterate over to display it to the component? or just a general point in the right direction.
EDIT: How im getting the data.
var options = {
url: url,
auth: {
user : 'xxx',
password : 'xxx',
}
}
app.get('/api/nfl', function (req, res) {
request(options, function (err, response, body){
if (err) {
console.log(err);
}
res.send(JSON.stringify(response.body));
})
});
As you thought since data is coming in an asynchronous way, you need to handle it somehow. When you try to get a property from an undefined object, you get an error like yours. So, you should use conditional rendering.
Before that, using componentWillMount instead of componentDidMount does not work since render does not wait for any of these two methods to finish its jobs. Actually, componentWillMount will be deprecated, so go with componentDidMount for the asynchronous operations.
Since you haven't shared the code how have you tried to get the data I'm giving a blind suggestion here.
render() {
console.log(this.state.jsonItems.fullgameschedule);
return this.state.jsonItems.fullgameschedule && (
<table>
<thead>
<tr>
<th>Test 1</th>
<th>Test 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>{this.state.jsonItems.fullgameschedule.lastUpdatedOn}</td>
</tr>
</tbody>
</table>
)
}
This is just an example. You can change it according to your needs.

How to Paginate dynamic AngularJS table?

How do I get pagination with ng-table-dynamic and $http working?
HTML specification of the table is
<table class="table-bonds table table-bordered table-hover table-striped"
export-csv="csv"
separator=","
show-filter="true"
ng-table-dynamic="bondsTable.bondsDataParams with bondsTable.bondsDataCols">
<tr ng-repeat="row in $data">
<td class="hand"
ng-repeat="col in $columns">{{::row.node[col.field]}}</td>
</tr>
The table creation code is:
self.bondsDataParams = new NgTableParams({
page: 1, // show first page
count: 5 // count per page
}, {
filterDelay: 0,
total: 0,
getData: function (params) {
return $http(bondsDataRemote).then(function successCallback(response) {
// http://codepen.io/christianacca/pen/mJoGPE for total setting example.
params.total(response.data.nodes.length);
return response.data.nodes;
}, function errorCallback(response) {
});
}
});
AngularJS 1.5.8
This is an excellent directive for pagination have a look at it . It has lots of options and its easy to use.
The main problem was mixing up loading the data via ajax and not supporting the filtering/pagination on the server side of the request.
Either provide all the data up-front so that the table can filter, or fully support the pagination, sorting and filtering on the server side.
Option 1. Load the data before hand. I used this option because my dataset is not that big and it seemed like the easiest way to allow people to use all the permutations of filtering sorting and downloading.
No total value is required here. The data is all loaded.
var Api = $resource('/green-bonds.json');
// Or just load all the data at once to enable in-page filtering, sorting & downloading.
Api.get({page: "1", count: "10000"}).$promise.then(function (data) {
self.bondsDataParams = new NgTableParams({count: 25}, {
dataset: data.results
})
});
Or fully support the lazy loading data API and set total. Uses getData: rather than just setting dataset.
var Api = $resource('/green-bonds.json');
this.bondsDataParams = new NgTableParams({}, {
getData: function (params) {
return Api.get(params.url()).$promise.then(function (data) {
params.total(data.count);
return data.results;
});
}
});
Note 1: By default $resource expects an object .get() for object, .query() for array. Also see isArray:. I didn't get this to work.
Note 2: params.url() provides $resource with the ng-table params. e.g. {page: "1", count: "10"}

How to fill backbone collection from JSON

Having the following code:
var Tasks = Backbone.Collection.extend({
url: 'http://localhost:5000/tasks'
});
var TaskView = Backbone.View.extend({
el: '.page',
render: function() {
var that = this;
var tasks = new Tasks();
tasks.fetch( {
success: function(tasks) {
var template = _.template($('#task-list-template').html(), {tasks: tasks.models});
that.$el.html(template);
}
})
}
});
var Router = Backbone.Router.extend({
routes: {
'' : 'home' // intentionally blank for the home page
}
});
// Display logic
var taskListView = new TaskView({ });
var router = new Router();
router.on('route:home', function() {
taskListView.render();
});
Backbone.history.start();
The following HTML:
<body>
<div class="container">
<h1>TODO app</h1>
<hr />
<div class="page"></div>
</div>
<script type="text/template" id="task-list-template">
<table class="table striped">
<thead>
<tr>
<th>Task</th>
<th></th>
</tr>
</thead>
<tbody>
<% _.each(tasks.tasks, function(task) { %>
<tr>
<td><%=task.get('task') %></td>
<td></td>
</tr>
<% }); %>
</tbody>
</table>
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script type="text/javascript" src="todoapp.js"></script>
</body>
and the following JSON return from an AJAX request:
{
"tasks": [
{
"id": 6314025183,
"task": "1"
}
]
}
I was wondering how to fill the Collection with the JSON data. I'm unable to fill my HTML table. I suspect my collection to not being filled properly.
How could I validate the content of the collection?
I'm I filling the collection the right way?
This code is based on this video from Thomas Davis available on youtube.
https://www.youtube.com/watch?v=FZSjvWtUxYk
You have two problems. One is code related and one is unfortunately API related.
The API problem can be solved in two ways, but I'll just lay it out first.
When a Collection requests data (from the url property) it expects an array of data. Unfortunately your API is returning an object:
{
"tasks": [
{
"id": 6314025183,
"task": "1"
}
]
}
This is pretty common in a lot of API design, and really speaks to a general misunderstanding of what makes APIs useful.
You'll notice the data you actually want is here in the tasks key of the object:
[
{
"id": 6314025183,
"task": "1"
}
]
It's an array of task objects, each with an id and - what I assume is - a task id.
Great, so you have two options here: you can fix the API so that a request to a collection route like /tasks returns the collection:
[
{
"id": 6314025183,
"task": "1"
}
]
Or, you can use Backbone's parse method to hack around the junk data.
From the documentation for Collection.parse:
Override this if you need to work with a preexisting API, or better namespace your responses.
Here's a quick example:
var Tasks = Backbone.Collection.extend({
'url': 'http://localhost:5000/tasks',
'parse': function( apiResponse ){
return apiResponse.tasks;
}
});
Note the information contained in that parse method that does not have a home. How do I know that the key of the response is tasks?
If I'm a new developer coming into this code, the fact is that I don't. It's tribal knowledge or knowledge I have to go searching for in the API raw response body. The better solution is to namespace the API response to return the collection as requested.
Your second problem is related to your code. In your code you have a Collection and a View and a template, but in your template, you're treating your tasks like a plain ol' javascript object, using underscore to loop over a key.
Instead, tell your collection how to represent it's data.
A collection is a set of related Models.
var Task = Backbone.Model.extend({});
var Tasks = Backbone.Collection.extend({
'url': 'http://localhost:5000/tasks',
'model': Task,
'parse': function( apiResponse ){
return apiResponse.tasks;
}
});
Now, when you hydrate your collection it will automatically create a model representing each set of discrete data.
You can change your view to look like this:
var TaskView = Backbone.View.extend({
'el': '.page',
'template': _.template($('#task-list-template').html()),
'render': function() {
var that = this;
var tasks = new Tasks();
tasks.fetch( {
success: function() {
that.$el.html( that.template( { 'tasks': tasks } ) );
}
})
}
});
Since all Backbone objects extend underscore in some way or another (see the docs for the details), you don't need to manually wrap the passed in collection in underscore. In fact, doing so will almost always create errors. Your template can look like this:
<html>
<body>
<div class="container">
<h1>TODO app</h1>
<hr />
<div class="page"></div>
</div>
<script type="text/template" id="task-list-template">
<table class="table striped">
<thead>
<tr>
<th>Task</th>
<th></th>
</tr>
</thead>
<tbody>
<% tasks.each( function( task ){ %>
<tr>
<td><%= task.get( 'task' ) %></td>
<td></td>
</tr>
<% }); %>
</tbody>
</table>
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script type="text/javascript" src="todoapp.js"></script>
</body>
</html>
The solution posted here is untested, but should allow you to make major debugging leaps even if it does not completely solve the problems

Angularjs, nested JSON & ng-repeat

I'm getting some JSON returned from a server for which I'd like to iterate over the key value pair label and value. I tried to access the values by using the following but I get nothing.
What am I missing for this to work?
HTML :
<tr ng-repeat="(label, value) in data[0].[label]">
<td>{{label}}</td>
<td>{{value}}</td>
</tr>
JSON input :
"data": {
"title": {
"label": "Title",
"value": "Mr"
},
}
<tr ng-repeat="title in data">
<td>{{title.label}}</td>
<td>{{title.value}}</td>
</tr>
(Assuming your Json is in a variable like $scope.data)

Categories

Resources