Angular 6 json object pipe not display data - html

I have an html file that is trying to display tasks for a project. The tasks are contained in an ref array inside the project schema that I get from MongoDB. When I try the code below:
<div class="card-body">
{{project.taskName | json}}
</div>
It displays the entire task object like this
[ { "project": [ "5bd973fe33bd3a09586c8eb2" ], "user": [], "_id": "5bd9776833bd3a09586c8eb3", "taskName": "Test task", "taskDescription": "This task is a test", "__v": 0 } ]
If I try {{project.task.taskName | json }} nothing gets displayed. How do I get the html to display the tasks name and description? Thanks!
EDIT: the json payload I receive
[
{
"team": [],
"task": [
{
"project": [
"5bd973fe33bd3a09586c8eb2"
],
"user": [],
"_id": "5bd9776833bd3a09586c8eb3",
"taskName": "Test task",
"taskDescription": "This task is a test",
"__v": 0
}
],
"_id": "5bd973fe33bd3a09586c8eb2",
"projectName": "Test project",
"projectDescription": "This is a test project",
"__v": 1
}
]

The best would be to have a small function which gets only the desired properties like taskName and taskDescription.
getCustomProjects() {
return this.project.map(p => {
return {
name: p.taskName,
taskDescription: p.taskDescription
}
});
}
html
<div class="card-body">
{{ getCustomProjects() | json}}
</div>
Note : You can call getCustomProjects and construct new array if in ts instead of html.
Working demo is here - https://stackblitz.com/edit/angular-2chhvd

I suspect the issue comes from the fact that your payload (project) is an array.
This should work fine:
{{ project.taskName[0].taskName | json }}
Hope that helps

You can pipe object using JSON {{project.task | json }}.
In your case project.task.taskName is not a object it is a string. So there is no need of pipe JSON. You can simply use
{{ project.taskName }}

You should not use |json with dot operator, if you need to print the whole object, use
<div class="card-body">
{{project | json}}
</div>
if you need taskName
<div class="card-body">
{{project.taskName}}
</div>
EDIT
You need to access using index since it is an array
<div class="card-body">
{{project[0].taskName}}
</div>

This code is work for me
array
abc = [
{
'team': [''],
'task': [
{
'project': [
'5bd973fe33bd3a09586c8eb2'
],
'user': [''],
'_id': '5bd9776833bd3a09586c8eb3',
'taskName': 'Test task',
'taskDescription': 'This task is a test',
'__v': 0
}
],
'_id': '5bd973fe33bd3a09586c8eb2',
'projectName': 'Test project',
'projectDescription': 'This is a test project',
'__v': 1
}
];
html
<div class=="card-body">
{{abc[0].task[0].taskName}}
</div>

Related

ANGULAR - How to properly handle multilevel JSON responses?

I am using a rest API, sending a GET request and getting the following JSON structure as a result:
{
"Id": "Sample Id",
"Attributes": {
"ReadOnly": false
},
"Children": [
{
"Id": "Sample Id1",
"Attributes": {
"ReadOnly": false
},
"Children": [
{
"Id": "Sample Id2",
"Attributes": {
"ReadOnly": false
}
}
]
},
{
"Id": "Sample Name2",
"Attributes": {
"ReadOnly": false
},
"Children": [
{
"Id": "Sample Id2",
"Attributes": {
"ReadOnly": false
}
}
]
}
]
}
It is basically a file system structure. So it is possible to have N objects(Id, Attributes{}, Children[]) in the root as well as in any other level of the structure.
Trying to explain a little bit better, the root node has its attributes and an array of N children that have its attributes and another Array of N children and so on...
How would be the correct way to handle this situation?
I have created a flat interface structure, looking basically like that:
export interface Hana{
Id: string,
Attributes: {
ReadOnly: string
}
}
I have also created a service and a component as follows:
Service
getHanaStructure(): Observable<Hana[]> {
const hanaStructs = this.http.get<Hana[]>(this.apiUrl);
this.messageService.add('HanaService: fetched struct');
return hanaStructs;
Component
hanaStructures$: Observable<Hana[]>;
getHanaStructure() : void {
this.hanaStructures$ = this.hanaService.getHanaStructure().pipe(map(data=> _.toArray(data)));
}
In order to show the data my HTML template looks like that:
<ul *ngIf="hanaStructures$ | async as hanaStructures else noData">
<li *ngFor="let hana of hanaStructures">
{{hana}}
</li>
</ul>
<ng-template #noData>No Data Available</ng-template>
The first problem is that I don't know to access the information by its key, I can just list their values. When I try something like {{ hana.Id }} instead of just {{ hana }} I got: *
"Property 'Id' does not exist on type 'Hana'"
The second issue is that I can only manage to list the first level data. I don´t know how access the Children of the Children of Children...
I am sure that the API is returning everything I need, but unfortunately I don´t know how to solve the problem.
Thanks,
Filipe
At first I would define the "Children" property in your Hana Interface as List of "Hana" Interfaces (This has some similarity with a resursive approach). Afterwards I would create a seperate Component, which gets displayed if you loop through the first layer of your children. This component should contain a loop of its own to loop through deeper nested components recursively.
Hope this was understandable and helps you. =)

How do you show JSON array in ionic using *ng-For when the keys are integer strings?

I'm using ionic 4 and I'm trying to get a JSON array using TransportAPI via http.get, however, they use integer strings as the key for the objects I'm trying to get, and then there are multiple arrays for each object, like so:
{
"departures": {
"25": [
{
"mode": "bus",
"line": "25",
"departure_time": "12:40"
},
{
"mode": "bus",
"line": "25",
"departure_time": "13:00",
}
],
"50": [
{
"mode": "bus",
"line": "50",
"departure_time": "12:46",
},
{
"mode": "bus",
"line": "50",
"departure_time": null,
},
{
"mode": "bus",
"line": "50",
"departure_time": "14:46",
}
]
}
}
This JSON array is being stored in "testArray: any;" and there are no problems with actually getting it as I can print it to the console log fine. After hours I only just found out you have to put number keys into bracket notation ie. ["25"] to access those, however I'm not sure how to go about this when using *ngFor, or even if you would. This is the rough code I'm trying to output:
<div *ngFor="let bus of testArray.departures"> //this is where I'm not too sure
<ion-item-divider>
<ion-label> bus line: {{ bus.line }}</ion-label>
</ion-item-divider>
<ion-item *ngFor="let time of bus"> //no idea what I'm doing here either
{{ time.departure_time }}
</ion-item>
</div>
Any help would be greatly appreciated!
Edit: this is the code I'm using to get the JSON file (missing imports and component etc to save space:
export class BusesPage implements OnInit {
testArray: any;
constructor(private http: HttpClient) {}
fillTestArray(){
this.http.get('assets/test.JSON').subscribe(data => {
this.testArray = data;
console.log(this.testArray);
});
}
ngOnInit() {
this.fillTestArray();
}
}
If this is data you wish to iterate through, you need to use the keyvalue pipe as this is an object. The *ngFor without is for iterating through arrays. This will let you iterate through the object.
You can then iterate through the array nested inside the object without the keyvalue pipe. which should show the data you want.
<div *ngIf="testArray"> // checks testArray exists
<div *ngFor="let bus of testArray.departures | keyvalue">
<div *ngFor="let data of bus.value">
<ion-item-divider>
<ion-label> bus line: {{ data.mode }}</ion-label>
<ion-label> bus line: {{ data.line }}</ion-label>
<ion-label> bus line: {{ data.departure_time }}</ion-label>
</ion-item-divider>
</div>
</div>
</div>
keyvalue pipe docs.
Angular's displaying data guide.

On watson conversation panel how to set the intent right on the respond json?

i am building a conversation on the watson conversaton, and in a point, togeter with my "response" json, i woul also link to set a new intent for the user, i tried to add this to the json, but with no result.
There is a way to do this?
As you can see in the Official documentation, you can use context variables for save values.
A context variable is a variable that you define in a node, and
optionally specify a default value for. Other nodes or application
logic can subsequently set or change the value of the context
variable.
So, in this case, you'll create in your JSON advance (like your example) something like:
{
"context": {
"intent": "fgts",
"confidence": 1
},
"output": {
"text": {
"values": [
"Your text here"
],
"selection_policy": "sequential"
}
}
}
And in your back-end application, you can access the value in the response JSON object from your POST /message, with something like: response.context.intent and response.context.confidence
Obs.: By default, Watson Conversation service will return the name of the intent that Watson recognizes and the confidence level.
If really after these instructions you want to use your method. You can see my example below:
{
"output": {
"text": {
"values": [
"text here"
],
"selection_policy": "sequential"
},
"intents": "test"
}
}
And your app return:
{ intents: [ { intent: 'helpBot', confidence: 0.5930036529133407 } ],
entities: [],
input: { text: 'ajuda' },
output:
{ text: [ 'text here' ],
nodes_visited: [ 'node_16_1511443279233' ],
intents: 'test',
log_messages: [] },
context:
{ conversation_id: '83d88b05-7c76-457d-bd5f-7820be455a3e',
system:
{ dialog_stack: [Object],
dialog_turn_counter: 2,
dialog_request_counter: 2,
_node_output_map: [Object],
branch_exited: true,
branch_exited_reason: 'fallback' } } }
See more about accessing values using Conversation Service.

Iterating through JSON object with Angular 2 ngFor

Before I write a service to get json, I just want to use some dummy json to test the front end. What's the correct way to iterate through json with ngFor? I tried the code below with a simple interface.
In the component.ts file (ngOnInit()):
var jsonSample = {
"name": "sample1",
"content": [
{
"id": "3",
"name": "Test",
"value": "45"
},
{
"id": "4",
"name": "Test2",
"value": "60",
}]
}
var items: Array<IContent> = jsonSample.content;
Then in the HTML:
<tr *ngFor='let content of items'>
<td>{{content.name | lowercase}}</td>
<td>{{content.id}}</td>
<td>{{content.value}}</td>
</tr>
Should I be trying to use JSON.parse instead?
Your *ngFor looks fine as far as json object traversal is concerned.
You do not need to do JSON.parse here as you have set an object directly.
In the case of receiving response from a service check here. You will be doing res.json() to parse and get json data from the Response object.
#torazaburo got it. I just had to change:
var items: Array<IContent> = jsonSample.content;
to
items: IContent[];
this.items = jsonSample.content;

Retrieving data from json using AngularJS

I am learning angular js from ground up and am currently trying to retrieve data from a json file.
I am using - nodejs, express, AngularJS.
Earlier I was getting an error "Unexpected token D" on using -
$http.get("/models/driversList.json").success(function(response){$scope.driversList = response})
which got resolved but now I'm getting something like this with the current code -
Drivers Championship Standings
1
I'm guessing the response is basically blank and therefore the "1" but am not getting as to why that is happening.
Below are my files -
/app.js
app.use('/models',express.static(path.join(__dirname, 'private/data/db/models')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/scripts',express.static(path.join(__dirname, 'public/javascripts')));
app.use('/styles',express.static(path.join(__dirname, 'public/stylesheets')));
/javascripts/app.js
angular.module('F1FeederApp', [
'F1FeederApp.controllers'
]);
/javascripts/controllers.js
angular.module('F1FeederApp.controllers', []).
controller('driversController', function($scope, $http) {
$http({
method: 'GET',
url: '/models/driversList.json',
data: {},
transformResponse: function (data, headersGetter, status) {
//This was implemented since the REST service is returning a plain/text response
//and angularJS $http module can't parse the response like that.
return {data: data};
}
}).success(function(response){ alert('worked'); $scope.driversList = response}).error(function(response) {
$scope.driversList = [
{
Driver: {
givenName: response,
familyName: 'Vettel'
},
points: 322,
nationality: "German",
Constructors: [
{name: "Red Bull"}
]
},
{
Driver: {
givenName: 'Fernando',
familyName: 'Alonso'
},
points: 207,
nationality: "Spanish",
Constructors: [
{name: "Ferrari"}
]
}
];
})
});
driversList.json
[
{
Driver: {
givenName: 'Eldorado',
familyName: 'Vettel'
},
points: 322,
nationality: "German",
Constructors: [
{name: "Red Bull"}
]
},
{
Driver: {
givenName: 'Fernando',
familyName: 'Alonso'
},
points: 207,
nationality: "Spanish",
Constructors: [
{name: "Ferrari"}
]
}
]
index.html
<!DOCTYPE html>
<html>
<head>
<title>F-1 Feeder</title>
<script src="/scripts/angular.min.js"></script>
<script src="/scripts/controllers.js"></script>
<script src="/scripts/app.js"></script>
</head>
<body ng-app="F1FeederApp" ng-controller="driversController">
<table>
<thead>
<tr><th colspan="4">Drivers Championship Standings</th></tr>
</thead>
<tbody>
<tr ng-repeat="driver in driversList">
<td>{{$index + 1}}</td>
<td>
{{driver.Driver.givenName}} {{driver.Driver.familyName}}
</td>
<td>{{driver.Constructors[0].name}}</td>
<td>{{driver.points}}</td>
</tr>
</tbody>
</table>
</body>
</html>
EDIT:
#rattanak
To answer the point 3, yes it works if I simply assign the array variable to the scope variable. The part in error() is the one which was working previously.
I also tried point 1 and it seems the json is present in "data", so I assigned response.data to driversList and now am getting this error -
Data:
[{Driver:{givenName:'Eldorado',familyName:'Vettel'},points:322,nationality:"German",Constructors:[{name:"Red Bull"}]}]
Error: [ngRepeat:dupes] http://errors.angularjs.org/1.4.7/ngRepeat/dupes?p0=driver%20in%20driversList.data&p1=string%3Ar&p2=r
at Error (native)
at http://localhost:3000/scripts/angular.min.js:6:416
at http://localhost:3000/scripts/angular.min.js:280:39
at Object.fn (http://localhost:3000/scripts/angular.min.js:129:401)
at n.a.$get.n.$digest (http://localhost:3000/scripts/angular.min.js:130:483)
at n.a.$get.n.$apply (http://localhost:3000/scripts/angular.min.js:133:512)
at h (http://localhost:3000/scripts/angular.min.js:87:376)
at K (http://localhost:3000/scripts/angular.min.js:91:499)
at XMLHttpRequest.z.onload (http://localhost:3000/scripts/angular.min.js:93:37)
indicating that there are duplicates
Your file driverlist.json does not contain valid JSON code. This code should be:
[
{
"Driver": {
"givenName": "Eldorado",
"familyName": "Vettel" },
"points": 322,
"nationality": "German",
"Constructors": [
{"name": "Red Bull"}
]
},
{
"Driver": {
"givenName": "Fernando",
"familyName": "Alonso"
},
"points": 207,
"nationality": "Spanish",
"Constructors": [
{"name": "Ferrari"}
]
}
]
Correct this and try again.
JSON always use double quotes (") never single quotes (')
For more info on correct JSON, see http://www.json.org/
It seems like the $http service does not resolve successfully. It is hard to tell without actually testing the code. With Chrome Dev Console, I would debug the code by:
Use console.log($scope.driversList) in the success function of the promise.
Use console.log(error) in the error function of the promise.
Were you able to get the code to work without using $http service, namely just assign array variable of the data to $scope.driversList.
I am happy to test it for you if you can provide a github link or something.