Change inner html dynamically from json - html

I have a json as follows -
{
"albums": {
"abc": "ABC",
"pqr": "PQR",
"lmn": "LMN",
"xyz": "XYZ"
}
}
In the html structure below, I want that each value in the json should be added in each subsequent p tag (in the same order)
<div>
<p><p>
<div>
<div>
<p><p>
<div>
<div>
<p><p>
<div>
<div>
<p><p>
<div>
(The divs are NOT be appended dynamically). I also don't want to pick each p tag and set value of each key to it one by one. I want this to happen automatically when I call the json ( which is stored in a separate file)
I am trying -
$(document).ready(function(){
$.getJSON("albums.json",
function (response) {
$.each(response.albums, function (key,value) {
$('p').each(function () {
$(this).html(value);
});
})
})
Doesn't give any output. Can anyone please tell me how to achieve this?
Thanks!!!

You can do it by getting the index of the item from your values and using that to target the right <p>:
var response = {
"albums": {
"abc": "ABC",
"pqr": "PQR",
"lmn": "LMN",
"xyz": "XYZ"
}
}
var $p = $('p');
Object.values(response.albums).forEach( (value,i) => {
$($p[i]).html(value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p></p>
</div>
<div>
<p></p>
</div>
<div>
<p></p>
</div>
<div>
<p></p>
</div>

Your HTML isn't valid (none of <p> or <div> are closed).
let json = {
"albums": {
"abc": "ABC",
"pqr": "PQR",
"lmn": "LMN",
"xyz": "XYZ"
}
};
let i = 0;
$.each(json.albums, function (key,value) {
$(`p:eq(${i})`).html(value);
i++;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p></p>
</div>
<div>
<p></p>
</div>
<div>
<p></p>
</div>
<div>
<p></p>
</div>

Related

XPath separate key and value of group

I'm trying to fetch data from a dd group that is not really well structured. The 'group' does have a DD wrapper but inside it's only p/div without a grouped wrapper around it:
[DD]
[P] Key
[DIV]
[P] Value
[P] Key
[DIV]
[P] Value
Is it possible to collect the data the proper way?
The html code I'm processing:
<dd class="product-specifications-v2__items">
<p class="product-specifications-v2__key">
EAN/UPC - product
</p>
<div class="product-specifications-v2__value">
<p class="product-specifications-v2__value-item">
7912372
</p>
</div>
<p class="product-specifications-v2__key">
Weight
</p>
<div class="product-specifications-v2__value">
<p class="product-specifications-v2__value-item">
2,170
<span>kg</span>
</p>
</div>
</dd>
I currently get the following result as a array:
{
"key": [
"EAN\/UPC - product",
"Weight"
],
"value": [
"7912372",
"2,170 kg",
]
}
And I need to get (without arrays):
{
"key": "EAN/UPC - product",
"value": "7912372"
},
{
"key": "Weight",
"value": "2,170 kg"
}
I'm fetching the data via an API with the following request:
{
"name":"attributes",
"selector":"div.product-specifications-v2__wrapper dl dd",
"targets":[
{
"name":"key",
"selector":"p.product-specifications-v2__key",
"dataType":"title"
},
{
"name":"value",
"selector":"div.product-specifications-v2__value p.product-specifications-v2__value-item",
"dataType":"title"
}
]
}
Using XPath 3.1 (for instance, inside the browser with Saxon-JS (https://www.saxonica.com/saxon-js/documentation2/index.html), also with Node) you can use a path expression that creates an XPath 3.1 XDM map with the key and value:
//dd[#class = 'product-specifications-v2__items']/p[#class = 'product-specifications-v2__key']!map { 'key' : normalize-space(), 'value' : following-sibling::div[#class = 'product-specifications-v2__value'][1]!normalize-space() }
const html = `<dd class="product-specifications-v2__items">
<p class="product-specifications-v2__key">
EAN/UPC - product
</p>
<div class="product-specifications-v2__value">
<p class="product-specifications-v2__value-item">
7912372
</p>
</div>
<p class="product-specifications-v2__key">
Weight
</p>
<div class="product-specifications-v2__value">
<p class="product-specifications-v2__value-item">
2,170
<span>kg</span>
</p>
</div>
</dd>`;
var htmlDoc = new DOMParser().parseFromString(html, 'text/html');
const results = SaxonJS.XPath.evaluate(`//dd[#class = 'product-specifications-v2__items']/p[#class = 'product-specifications-v2__key']!map { 'key' : normalize-space(), 'value' : following-sibling::div[#class = 'product-specifications-v2__value'][1]!normalize-space() }`, htmlDoc, { 'xpathDefaultNamespace' : 'http://www.w3.org/1999/xhtml' });
console.log(results);
<script src="https://www.saxonica.com/saxon-js/documentation2/SaxonJS/SaxonJS2.rt.js"></script>
The JavaScript API of Saxon-JS returns the sequence of XDM maps as an array of JSON objects to JavaScript.

Separate and display multiple json value in different span tag in reactjs

I have a json object called blogData with json data. Inside the json obj the tags key may have multiple tag values. I would like to display the tags values separately in span tag while iterating using map function.
Now multiple tags are displaying in a single span tag ( please see below) How can I fix this ?
const blogData = [
{
"id" : 1,
"title":"Cypress tests",
"images":"/images/image1.jpg",
"description": "Add the E2E cypress UI tests",
"tags": "cypress"
},
{
"id" : 2,
"title":"Jmeter tests",
"images":"/images/image2.jpg",
"description": "Performance test using Jmeter tool",
"tags": ["jmeter", "performance"]
},
{
"id" : 3,
"title":"Basic Unix commands",
"images":"/images/image3.jpg",
"description": "Learn basic unix commands in git bash",
"tags": "unix"
},
{
"id" : 4,
"title":"Postman",
"images":"/images/image4.jpg",
"description": "Api testing using postman",
"tags": ["postman", "api"]
},
]
Home.js
const [searchResults, setSearchResults] = useState([]);
<div className="container">
{
searchResults.map(({ id, title, images, description, tags }) => (
<div key={id} className="column-center">
{/* <img className="blogImage" key={images} src={images} alt="image"></img> */}
<div className="blogtitle">
<span key={title}>{title}</span>
</div>
<section>
<p className="blogdescription" key={description}>{description}</p>
</section>
<section className="col1">
<span key={tags}>{tags}</span>
</section>
<section className="col2">
<a>Read more {'>'}{'>'}</a>
</section>
</div>
))
}
</div>
I think this what you are after.
Sandbox
<section className="col1">
{Array.isArray(tags) ? (
tags.map((tag) => (
<span style={{ marginRight: "10px" }}>{tag}</span>
))
) : (
<span>{tags}</span>
)}
</section>
You could make this code much simpler be having the tags field always be an array even if there is a single element.

How to bind JSON object key value pair separately to angular template

And i have a dynamic json coming from an API as below:
{123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra",...}
I have below HTML code written in my template in which I am getting image-1, image-2 logos from my assets folder
<div class="row">
<div class="col-6" (click)="cityClick('Bangalore')">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
Bangalore
</div>
</div>
<div class="col-6" col-6 (click)="cityClick('Mumbai')">
<div id="image_block" class="img-2">
// my image-2 logo goes here
</div>
<div id="text_block" class="img-text">
Mumbai
</div>
</div>
</div>
How to get the key of the json when i click on image and also display the text below the image from the corresponding key-value.
And when i click i should be able to pass the key and text inside the click event. Please help as i am new to Angular!
First convert this JSON into an JavaScript/TypeScript array like below:
var json = {123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra" };
var jsonToBeUsed = [];
for (var type in json) {
item = {};
item.key = type;
item.value = json[type];
jsonToBeUsed.push(item);
}
This will result in data like below:
Now use NgFor in the template to bind array. (Refer this for NgFor)
<div class="row">
<div *ngFor="let item of array">
<div class="col-6" (click)="cityClick(item)">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
{{item.value}}
</div>
</div>
</div>
</div>
We have passed the whole object in the click event. You can read any of the desired property from the object in click event handler which you will write in the component.
For your special requirement, you can use below markup:
<div class='row' *ngFor='let index of array; let i = index; let even = even'>
<div *ngIf="even" class='col-6' (click)="cityClick(array[i])">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
{{array[i].value}}
</div>
</div>
<div *ngIf="!even" class='col-6' (click)="cityClick(array[i])">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
{{array[i].value}}
</div>
</div>
</div>
Use this below function in your code:
getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
And use as
var dynamicJson = {123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra"}
cityClick(value){
var key = this.getKeyByValue(this.dynamicJson, value);
console.log(key);
}
{123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra",...}
Do you have influence on that JSON? This highly looks like a design issue for me. I assume those numbers are id's. I believe somethings like this should be better:
[{id: "123", name: "Mumbai"}, {id: "456", name: "Bangalore"}, {id: "789", name: "Chennai"}, {id: "101", name: "Andhra"},...}]
In that case you receive an array of cities, which could be an interface to parse to.
export interface City {
id: string;
name: string;
}
And you can easily render it in html by using *ngFor
<div *ngFor="let city of cities">
<!--do something with city.id and city.name-->
</div>
<div *ngFor let value of json |keyvalue > </div>

Unable to show data in correct format using two way binding

I have a page here in which i have got headings and paragraphs and pictures and some other data. I am getting data from backend which also contains an array with different properties that will be bringing data in it. I need to show that data on my page according to the properties. Here is the data that i am getting from backend
{
"result": {
"slogan": "Majeed",
"bannerImage": "data:image/png;base64,...",
"schoolName": "JPSC",
"schoolTenancyName": "JPSC",
"logo": null,
"city": "Harbel",
"county": "Kakata",
"district": "Kakata",
"addressline": "319-Hadi Street, Alhamd COlony, Allama Iqbal Town",
"profilePageContents": [{
"id": "355156f4-3499-4883-846d-e41bed8a2765",
"heading": "Yamaha",
"paragraph": "Hello Guys this is ahsan nissar and this is my school profile page and you can",
"image": "data:image/png;base64,...",
"alignment": "Left"
},
{
"id": "d06ce9a5-94a9-4433-adda-ed7efe93f5b2",
"heading": "Hello friends",
"paragraph": "I am Ahsan and this is my school. No one can enter here without permission.",
"image": "data:image/png;base64,...",
"alignment": "Left"
}
]
}
Now in the page i need to show the profilePageContents in a way that i will take property into consideration and according this property i will show my picture and paragraph data in the page. If the paragraph is enclosed in class="paraLeft" then alignment=Left condition will trigger and will show paragraph data. Till now i was able to show data in this way
but i want to show pargrpah in the correct way. You can see in the picture that i am getting all paragraphs which i do not want.
Here is my typeScript Code
publicData: GetPublicProfilePage = new GetPublicProfilePage();
active: boolean = false;
saving: boolean = false;
selectedFile: File;
image_size: boolean;
image_format: boolean;
dataa: {
image: string,
paragraph: string,
heading: string
}
imageUrl: string;
data: string[];
align: string[];
para: string;
para2: string;
public base64textString: string;
constructor(
injector: Injector,
private router: Router,
private _profileService: ProfileServiceProxy
) {
super(injector);
}
ngOnInit() {
this._profileService.GetPublicProfilePage('JPSC')
.finally(() => {
this.saving = false;
})
.subscribe((result: GetPublicProfilePage) => {
this.publicData = result;
this.data = this.publicData.profilePageContents.map(a => a.paragraph);
this.align = this.publicData.profilePageContents.map(a => a.alignment);
for (let i = 0; i < this.align.length; i++) {
if (this.align[i] === 'Left') {
for (let j = 0; j < this.data.length; j++) {
if (document.getElementsByClassName('paraLeft')) {
this.data[i] = this.para[i];
}
}
}
}
})
}
my HTML Code
<section>
<div class="paraLeft">
<div class="row clearfix">
<div class="imgRight"><img class="img-responsive" src="/assets/images/boss.png" alt="Smiley face" style="float:right;width:400px;height:200px;"></div>
<p>
<span align="left" style="float:left; font-size: 20px; font-weight: bold;">Information</span><br>
<br><br>{{data}}
</p>
</div>
</div>
</section>
<section>
<div class="paraRight">
<div class="row clearfix">
<div class="imgLeft">
<img class="img-responsive" src="/assets/images/boss.png" alt="Smiley face" style="float:left;width:400px;height:200px;">
</div>
<p>
<span align="left" style="float:left; font-size: 20px; font-weight: bold;">Information</span>
<br><br>{{data}}
</p>
</div>
</div>
</section>
<section>
<div class="paraLeft">
<div class="row clearfix">
<div class="imgRight">
<img class="img-responsive" src="/assets/images/boss.png" alt="Smiley face" style="float:right;width:400px;height:200px;">
</div>
<p>
<span align="left" style="float:left; font-size: 20px; font-weight: bold;">Information</span>
<br><br>{{data}}
</p>
</div>
</div>
</section>
I really need to figure out this thing and if there is a way to solve this using angular class binding or using DOM or anything than please help me.
The below part in your code is not necessary:
this.data = this.publicData.profilePageContents.map(a => a.paragraph);
this.align = this.publicData.profilePageContents.map(a => a.alignment);
for (let i....
The solution would be:-
1. Use the even or odd properties of the *ngFor loop, you can then know whether to assign the class paraLeft or paraRight. https://angular.io/api/common/NgForOf
2. Use flexbox to align left or right
Below is the sample solution: https://stackblitz.com/edit/so-list

Get nested values from JSON with angularJS

I need to get nested products from JSON to my html in <div ng-repeat="order in orders"></div> I tried many versions of getting products values(name, description etc.) but none of them works. How to do this ?
JSON:
[
{
"id":3,
"date":"00:00:00",
"user":{
"id":1,
},
"orderState":{
"id":1,
},
"products":[
{
"id":1,
"name":"Bosch POF 1200",
"description":"1200W",
"enabled":true,
"price":459,
},
{
"id":9,
"name":"Graphite 58G782",
"description":"a",
"enabled":true,
"price":429,
}
]
}
]
Controller
OrdersService.retrieveAllByCurrentUser().then(function(response) {
$scope.orders = response.data;
console.log(response.data);
}, function(error) {
registerError(error, 'retrieving all orders');
});
The ng-repeat directive creates a new scope, which means that you should be able to loop through the products within it like this:
<div ng-repeat="order in orders">
<div ng-repeat="product in order.products"> e.g. {{product.name}} </div>
</div>
I would also advise to write a directive for dealing with that kind of stuff, because your code can get unreadable really fast. Don't take my word for it though as I am no Angular expert.
Create a nested ng-repeat like this to access the products information:
<div ng-repeat="order in orders">
<div ng-repeat="product in order.products">
<h1 ng-bind="product.name"></h1>
<p ng-bind="product.description"></p>
</div>
</div>
For each order it will go into order.products and loop out the information as product, then you can access the information in product via dot notation, like product.name for example.
You can do nested ng-repeat in html
<div ng-repeat="order in orders">
<div ng-repeat "product in order.products">
<span>{product.name}}</span>
<span>{{product.description}}</span>
</div>
</div>