Need to read relevant JSON data on home.html page with click - json

I have this JSON in my home.ts
public json_html = {
"button1":"<p><b>first section<b></p>",
"button2":"<p>second section</p>",
"button3":"<p><b>third section<b></p>",
}
On my home.html I want to see three links - button1 , button2 , button3 . If button 1 is clicked, then need to show its data using code like this:
document.getElementById("c1").innerHTML+= "clicked content";
How can I achieve this ?

I'm going to assume you might have more buttons, so let's build a loop. But first, Angular2's ngFor directive doesn't let you iterate over objects, they must be arrays. So we can grab get a array of keys first in your constructor:
this.buttons = Object.keys(this.json_html);
Then we can utilize the ngFor directive in our home.html
<button ion-button *ngFor="let button of buttons" (click)="selectedButton = button">
{{ button }}
</button>
And then we can add to home.html a div to show the html data:
<div *ngIf="selectedButton" [innerHtml]="json_html[selectedButton]">
</div>
Now this is really simple, because your coding your HTML into the JSON object. I'd suggest looking at a tabs example project on Ionic when the data gets more complex.

To achieve that, you should follow this steps:
Create an array of object keys using this.keysArr = Object.keys(this.json_html), because we can't iterate through objects in view
Iterate through this keys using <div *ngFor="let button of keysArr"></div>
Inside the div from step 2, declare another one: <div [innerHTML]="json_html[button]"></div>
I'm using [innerHTML] instead of the regular document.getElementById("c1").innerHTML+= "clicked content", because it looks like "the Angular way". Here is the working example (in app folder):
https://stackblitz.com/edit/angular-9pyhg3?file=app/button-overview-example.html
UPDATE
"It is showing me data of all 3 together, i want to see button1, button2, button3 and on clicking it to show data of the clicked element. Whereas currently it is directly showing data, can you update stackblitz"
Sure, here it is:
https://stackblitz.com/edit/angular-9pyhg3-e49qys?file=app/button-overview-example.html

Related

AngularMaterial mat-slide-toggle toogle working only for the first component

I have an angular project I am developing using angular material for a slide toggle and text fields, and cdk drag and drop for drag and drop functionality. I am pretty new to angular libraries and angular in general.
I have run into an issue where the slide toggle is only toggling the first element inside an *ngFor loop. I have tried adding a let i = index to the ngFor and it is always passed as 0 no matter which toggle you select, however if I place {{ i }}, it will show up as the correct index. I am at a loss.
https://stackblitz.com/edit/angular-yezv9a
If you go to the project at that link, and toggle the test 2 or 3 toggle, it will shift the first 1 and I can not seem to figure out why
Any help is appreciated
If I understand you correctly, There is one issue in your code is mat-slide-toggle element has an id which is repeating in ngFor
<mat-slide-toggle id="toggle" color="primary" (change)="onToggle(button)" [checked]="button.enabled"></mat-slide-toggle>
I removed the id attribute and found working correctly, based on my understanding you can find a fork of working example in below url
https://angular-yezv9a-bac1jz.stackblitz.io/
Make the id attribute as empty
Will work as expected

How to create a reusable ionic-card to populate it with different data?

I am new to ionic development, but i am familiar with its concepts of ionic-cards that shows data in cards . The issue i am having is how to design a ionic-card in its template file where all data including it's label (that are static most of the time) is dynamic.
I don't want to create multiple ionic-cards, and since the data is different every time for every card , i just want my single ionic card to display different data dynamically (including it's label.
I hope i have explained my point well. Any help would be appreciated.
If I understand correctly you have an array of data that you want to display on a ion-card.
If so you, what you need to do is as follows:
On your .ts file
public myArray: any = [];
constructor(...){}
ionViewWillEnter() {
this.myArray = //populate your array
}
And on your HTML file:
<ion-content>
<ion-card *ngFor='let element of myArray'>
// Populate the cards
<ion-card-title> {{ element.title }} </ion-card-title>
</ion-card>
</ion-content>

Expanding multiple divs independently based on Boolean variable value

I have a list of mat-card components that are individually expanded on clicking a button within each card. So far the Boolean variable has been defined within the HTML code itself rather than in the Angular .ts file, however I am wanting to transition this to use a Boolean in the .ts file.
I have attempted to assign a simple Boolean, however I now find that all of the cards expand at the same time...
I know what is wrong, but I cannot think about the way in which to fix it :-/
Here is a stackblitz
Since your cards are created with an ngFor directive from an array, the expanded data should be stored in an array too!
.ts
thisExpands = [];
.html
[ngClass]="{expanded: thisExpands[x]}"
(click)="thisExpands[x] = !thisExpands[x]"
Demo

Pass data from nested Components Angular 2

I have a component where with a *ngFor print some boxes defined in an other component like this:
<div>
<commponentB *ngFor="let a of list"></componentB>
</div>
where "list" is a list ok object like this:
this.list=[{"id":"3","nome":"app3","posizione":3},{"id":"1","nome":"app1","posizione":1},{"id":"2","nome":"app2","posizione":2}];
I have to populate all the component. How can I transfer data from this two component?
TY
EDIT1:
the problem is that the list is splitted into 2 list for the repeat in 2 different bootstrap columns so the situation is this:
<div>
<commponentB *ngFor="let a of list1"></componentB>
</div>
<div>
<commponentB *ngFor="let a of list2"></componentB>
</div>
and the component is like that:
<div>
<span>{{name}}</span>
</div>
if I pass all the list I can't know how to populate the component at the right position (sorry if I don't explain the problem very well)
Since your components are directly linked, you can use the #Input() component interaction to send data from the parent to the child.
Here is a link from the official documentation :
https://angular.io/guide/component-interaction#pass-data-from-parent-to-child-with-input-binding
If you can't do that model because of a router interaction, or components are too "far" away so it's too much work to setup several inputs, you can use a shared service to share the data from one to another component.
https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service
if you want to pass your list to componentB you can define Input() property in componentB and then pass your list
<div>
<commponentB [list]="list"></componentB>
</div>
export class ComponentB{
#Input() list: any[];
}
Update Ok maybe I'm not getting your issue, even if you have to pass different inputs to same component you can do that. Check out this plunker:

how to create a gloabal variable in angularjs?

I'm trying to develop a shopping cart where I have list of products , when user clicks on each product details will be displayed ,I want to add each product to global map or something when user clicks the add to cart button ,how can I achieve this?
for better understanding here is my link to plunker: https://plnkr.co/edit/oo05d6H6AxuJGXBAUQvr?p=preview
This is my details page where I want to provide user with add to cart option:
<!DOCTYPE html>
<p>ItemName: {{itemName}}</p>
<p> ItemPrice: {{itemPrice|currency}}</p>
<p>ItemRating:{{itemRating}}</p>
<img src="{{itemImage}}">
<p><input type = "submit" value = "Add to Cart" ng-click = "addProduct()"></p>
In your case a simple place to store the cart in the main controller, as it is accessible from the child controllers of the nested views. So here is how the addProduct() function could be implemented:
app.controller('mobileController', function($scope) {
$scope.items = ...
$scope.cart = [];
$scope.addProduct = function(item) {
$scope.cart.push(item);
}
});
and so the function could be called from the product details controller, provided you allow access to the viewed item in it:
<input type= "submit" value="Add to Cart" ng-click="addProduct(item)">
Since then you can display your updated cart in your main controller view (or in a child view of it, as it remains accessible):
<div ng-repeat="item in cart track by item.name">
<li>{{item.name}}</li>
</div>
Should you want to add the same item multiple times, you'll have to display orders (or product serial numbers) instead of products.
Find the forked plunker here.
P.S.: Another option would be to store the cart in an Angular service, which would be injected in any controller that needs it.
P.P.S.: I kept on using the $scope as you did, but you should update your code to the latest Angular usages, such as using the controllerAs syntax and using controllers classes that can refer this (and a controller's name prefix in the templates) instead.
Try this version.
There is acartService defined here and injected in your ItemCtrl. All items are stored in a cart array inside the cartService.
Be aware that this works until you refresh the page. If you want to persist this cart variable so that it doesn't get erased during page refresh, you should look into localStorage or $cookies.