Angular 6 : How to display 2 dimension array - arrays

This my array data that I get from service:
How I can use this array on my component
<div *ngFor="let i of service$">
<div class="row">
<div class="col-lg-4" *ngFor="let j of i">
{{j.title}}
</div>
</div>
</div>
My component.ts, I call getService() in my constructor.
service$: any;
getService() {
this.serviceService.get_service()
.pipe(first())
.subscribe(
data => {
this.service$ = data;
console.log(this.service$);
},
error => {
this.error = error;
});
}

Use Async pipe which displays the data that comes from API.
<div *ngFor="let i of service$ | async">
<div class="row">
<div class="col-lg-4" *ngFor="let j of i">
{{j.title}}
</div>
</div>
</div>

Your service call should look like
service$: any;
ngOnInit(){
this.service$ = this.serviceService.get_service().pipe(
catchError(error => this.error = error)
);
}

Your have some issues in TS I believe. First of all define variable like :
service$: any[] = [];
Then remove pipe() and use below code :
getService() {
this.serviceService.get_service()
.subscribe(
data => {
this.service$ = data;
console.log(this.service$);
},
error => {
this.error = error;
});
}
I hope you are returning get_service() some thing like this :
return this.http.get('YOUR_URL')
.map((response) => response.json());
Your HTML looks fine to me.

Related

Angular doesn't retrieve updated_at in laravel

i'm trying to retrieve the updated_at time but it gets the created_at time instead even when i passed it in the angular scope function
and renders the incorrect date on created_at after the update has been made
My console reads when updated
1 second ago
so it works but its not getting passed in the view correctly.
PostController
public function update(Post $post)
{
//
$data = request()->validate([
'body' => 'required|string'
]);
$this->authorize('update', $post);
$post->update($data);
$data['id'] = $post->id;
$data['updatedAt'] = $post->updated_at->diffForHumans();
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
public function getPosts()
{
$posts = Post::with('user')
->with(['likes' => function ($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
}])
->get();
$response = new Response(json_encode($posts));
$response->headers->set('Content-Type', 'application/json');
$data = $posts->map(function(Post $post)
{
$user = auth()->user();
if($user->can('delete', $post)) {
$post['deletable'] = true;
}
if($user->can('update', $post)) {
$post['update'] = true;
}
$post['likedByMe'] = $post->likes->count() == 0 ? false : true;
$post['likesCount'] = Like::where('post_id', $post->id)->get()->count();
$post['createdAt'] = $post->created_at->diffForHumans();
$data['updatedAt'] = $post->updated_at->diffForHumans();
return $post;
});
return response()->json($data);
}
main.js
$scope.updatePost = function(post){
$http.post('/auth/upost/' + post.id, {
body: post.body,
updatedAt:post.updatedAt
}).then(function(result, status, headers, config){
$scope.updatedAt = result.data.updatedAt;
console.log($scope.updatedAt);
$scope.myposts.push($scope.updatedAt);
});
};
html
<div id="mypost" class="col-md-8 panel-default animated zoomIn" ng-repeat="post in myposts ">
<div id="eli-style-heading" class="panel-heading"><% post.user.name %></div>
<div class="panel-body panel" ng-init="getLikeText(post); getLikecount(post)">
<i style="color:tomato; float:right; font-size:24px;" ng-click="like(post); toggle = !toggle"
ng-class="{[noheart] : !post.likedByMe, [heart]: post.likedByMe }">
<h3 style="font-size:20px; margin:20px 0px; text-align:center;" ng-bind="post.likesCount"> </h3>
</i>
<figure>
<p class="mybody" ng-model="post.body" editable-text="post.body" e-form="textBtnForm"> <% post.body %></p>
<p name="post.created_at" > <% post.createdAt %> <% post.updatedAt %> </p>
</figure>
<span>
<i style="color:red;" class="glyphicon glyphicon-remove" ng-click="deletePost(post)" ng-if="post.deletable"></i>
<button ng-if="post.update" class="btn btn-default" ng-click="textBtnForm.$show()" ng-hide="textBtnForm.$visible">
Edit
</button>
<span><button ng-if="post.update" type="submit" class="btn btn-primary" ng-click="updatePost(post)">Update</button></span>
</span>
</div>
</div>
this is the correct code my bad for this silly question guys.
public function getPosts()
{
$posts = Post::with('user')
->with(['likes' => function ($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
}])
->get();
$response = new Response(json_encode($posts));
$response->headers->set('Content-Type', 'application/json');
$data = $posts->map(function(Post $post)
{
$user = auth()->user();
if($user->can('delete', $post)) {
$post['deletable'] = true;
}
if($user->can('update', $post)) {
$post['update'] = true;
}
$post['likedByMe'] = $post->likes->count() == 0 ? false : true;
$post['likesCount'] = Like::where('post_id', $post->id)->get()->count();
$post['createdAt'] = $post->created_at->diffForHumans();
// $data['updatedAt'] = $post->updated_at->diffForHumans();
//calling again if the post has been updated
$post['createdAt'] = $post->updated_at->diffForHumans();
return $post;
});
return response()->json($data);
}
main.js
remove this its useless and renders out a box
$scope.myposts.push($scope.updatedAt);
html
<% post.createdAt %> is all you need it will render both the created time and updated time

when ng-repeat list of folders updates wrong

I have receive listof objects with names: F1,F2,F3,F4
when I make call to server, I receive new list F1,F2,F3,F5,F4
when I apdate ng-repeat list:
vm.folders = data.content.items;
it shows next list: F1,F2,F3,F4,F4
where am I wrong? here is my html code:
<div ng-repeat="folder in vm.folders track by $index" ng-init="openInput=false;">
<div layout="row" ng-init="folderName = vm.getIterationName(folder.metadata)" >
<div >
</div>
<div >
<span ng-click="showChildren[$index]=!showChildren[$index]" class="capitalize" ng-dblclick="openInput = true;$event.stopPropagation();" ng-show="!openInput">{{folderName}}</span>
</div>
</div>
</div>
js update method:
function updateIterations(data) {
if (data.ok === true) {
if(angular.toJson(vm.folders) != angular.toJson(data.content.items)) {
vm.folders = data.content.items;
}
} else if (data.ok == false) {
console.log ('Error:iteration request: {ok: false}');
$interval.cancel(intervalRequests);
}
}
fixed!
in
<span ng-click="showChildren[$index]=!showChildren[$index]" class="capitalize" ng-dblclick="openInput = true;$event.stopPropagation();" ng-show="!openInput">{{folderName}}</span>
instead of {{folderName}} i've used:
<span ng-click="showChildren[$index]=!showChildren[$index]" class="capitalize" ng-dblclick="openInput = true;$event.stopPropagation();" ng-show="!openInput">{{vm.getIterationName(folder.metadata)}}</span>

Filter object array with pipe Angular 2

I have a
class:
export class Todo {
public id: number;
public name: string;
public isCompleted: boolean;
public dateCreated: Date;
public userName: string;
}
A service:
getTodos(): Observable < Todo[] > {
return this.http.get(this.todosUrl)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || {};
}
In my component:
getTodos(){
this.todoService.getTodos()
.subscribe(
todos => this.todos = todos,
error => this.errorMessage = <any>error
);
}
And html file:
<div class="ui large selection animated divided list">
<a *ngFor="let todo of (todos | todoFilter:false)" class="item">
<div class="right floated content">
<div class="ui vertical animated negative button" tabindex="0">
<div class="hidden content">Delete</div>
<div class="visible content">
<i class="fa fa-trash" aria-hidden="true"></i>
</div>
</div>
</div>
<i class="minus square outline icon"></i>
<div class="content">
<div class="header">{{todo.name}}</div>
<div class="description">{{todo.dateCreated | date:"MMM-dd-yyyy"}}</div>
</div>
</a>
</div>
The problem is, when I try to use this pipe to filter the completed todos, I keep getting an error that say Cannot read property filter of undefined.
Did I do something wrong or are there any ways to filter it without using an pipe?
My pipe:
transform(allTodos: Todo[], args?: boolean){
if (allTodos === null) {
return null;
}
return allTodos.filter(todo => todo.isCompleted);
}
Thank you.
Try to replace the if (allTodos === null) to just if (!allTodos)
I think the problem is that you're getting to the .filter even while your this.todos is still empty since you're only checking that it isn't null.

Observable issue with async pipe

im using a library that help me to sort a list with drag-and-drop.
and the list that im giving it is an Observable of the list type, and then im using async to read it in the html, its very simple and looks like this:
#Injectable()
export class MyCmp implements OnInit {
myList: Observable<MyListType[]>;
showingList = false;
constructor(private _myService: MyService) {
};
public showListData(): void {
this.showingList = true;
this.myList = this._myService.getListData();
}
}
And this is the html:
<button md-button
(click)="showListData()"
title="">Show List
</button>
</div>
<md-content>
<div *ngIf="showingList">
<div dnd-sortable-container [sortableData]="myList | async">
<div class="list-bg" *ngFor="#item of myList | async; #i = index" dnd-sortable [sortableIndex]="i">
ID: {{item.id}} <p></p> Name: {{item.name}}
</div>
</div>
<div>Current List {{myList | async | json}}</div>
</div>
</md-content>
now this does not work, BUT, if I do this in my component instead of myList: Observable<MyListType[]>;
I do:
myList = this._myService.getListData();
and then in the html pass myList it works great...
I dont get it!! drive me crazy :/
please help
getListData() like like this:
public getListData(): Observable<MyListType[]> {
return this._someApiService.getCurrentListData().map(res => res.info);
}

how get the list of selected items in angular.js

Here I am using angular.js to show a list of people
<div class="recipient" ng-repeat="person in people">
<img src="{{person.img}}" /> person.name
<div class="email">person.email</div>
</div>
$scope.people = [{id:1}, {id:2}, {id:3}, {id:4}];
The looks is like below
What I want to do is I can select multiple items and by click a OK button, I can get a list of selected items. so If I select id 1 and id 2, then I want to get return a list of [{id:1},{id:2}]
How could I implement it in angular.js
Well I guess that if you're looping through a collection of people using a ng-repeat, you could add the ng-click directive on each item to toggle a property of you're object, let's say selected.
Then on the click on your OK button, you can filter all the people that have the selected property set to true.
Here's the code snippet of the implementation :
<div class="recipient" ng-repeat="person in people" ng-click="selectPeople(person)">
<img src="{{person.img}}" /> person.name
<div class="email">person.email</div>
</div>
<button ng-click="result()">OK</button>
function demo($scope) {
$scope.ui = {};
$scope.people = [{
name: 'Janis',
selected: false
}, {
name: 'Danyl',
selected: false
}, {
name: 'tymeJV',
selected: false
}];
$scope.selectPeople = function(people) {
people.selected = !people.selected;
};
$scope.result = function() {
$scope.ui.result = [];
angular.forEach($scope.people, function(value) {
if (value.selected) {
$scope.ui.result.push(value);
}
});
};
}
.recipient {
cursor: pointer;
}
.select {
color:green;
}
.recipient:hover {
background-color:blue;
}
<script src="https://code.angularjs.org/1.2.25/angular.js"></script>
<div ng-app ng-controller="demo">
<div class="recipient" ng-repeat="person in people" ng-click="selectPeople(person)" ng-class="{ select: person.selected }">
<div class="name">{{ person.name }}</div>
</div>
<button ng-click="result()">OK</button>
Result :
<ul>
<li ng-repeat="item in ui.result">{{ item.name }}</li>
</ul>
</div>
If you only want to show checked or unchecked you could just apply a filter, but you would need to toggle the filter value from undefined to true if you didn't wan't to get stuck not being able to show all again.
HTML:
<button ng-click="filterChecked()">Filter checked: {{ checked }}</button>
<div class="recipient" ng-repeat="person in people | filter:checked">
<input type='checkbox' ng-model="person.isChecked" />
<img ng-src="{{person.img}}" />{{ person.name }}
<div class="email">{{ person.email }}</div>
</div>
Controller:
// Apply a filter that shows either checked or all
$scope.filterChecked = function () {
// if set to true or false it will show checked or not checked
// you would need a reset filter button or something to get all again
$scope.checked = ($scope.checked) ? undefined : true;
}
If you want to get all that have been checked and submit as form data you could simply loop through the array:
Controller:
// Get a list of who is checked or not
$scope.getChecked = function () {
var peopleChkd = [];
for (var i = 0, l = $scope.people.length; i < l; i++) {
if ($scope.people[i].isChecked) {
peopleChkd.push(angular.copy($scope.people[i]));
// Remove the 'isChecked' so we don't have any DB conflicts
delete peopleChkd[i].isChecked;
}
}
// Do whatever with those checked
// while leaving the initial array alone
console.log('peopleChkd', peopleChkd);
};
Check out my fiddle here
Notice that person.isChecked is only added in the HTML.

Resources