Angular 4: outputing data with *ngFor not working - json

I'm working on this app with HttpClient, which gets data from a local json file containing images and description (the images are also local) I can log the data (in local array), but I'm having trouble outputing it in the view. This is the request:
export class AppComponent {
spaceScreens:Array<any>;
constructor(private http:HttpClient) {
this.http.get('assets/data/data.json')
.subscribe(data => {
this.spaceScreens = data['results'];
console.log(data);
}, (err: HttpErrorResponse) => {
if (err.error instanceof Error) {
console.log('An error occurred:', err.error.message);
} else {
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
}
});
}
}
The JSON:
{
"screenshots": [
{
"img": "assets/images/space1.jpg",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"liked": "0"
}, //etc
The HTML:
<mat-card *ngFor="let spaceScreen of spaceScreens; let i = index" >
<img mat-card-image src="{{ spaceScreen.img }}">
<mat-card-content>
<p>{{ spaceScreen.description }}</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>
<i class="material-icons md-18" >favorite</i> LIKE
</button>
<button mat-button>
<i class="material-icons md-18">delete</i> DELETE
</button>
</mat-card-actions>
</mat-card>
This is the log:
I guess the issue has to do with the map? But if I try to map the response I get the word underlined. Can someone give me a help? Thank you

this.spaceScreens = data['results'];
should become
this.spaceScreens = data['screenshots'];
to match your json format.

change
<img mat-card-image src="{{ spaceScreen.img }}">
to
<img mat-card-image [src]="spaceScreen.img">
In angular 2+ you should prefer binding to attributes rather then setting them with string interpolation.

Try to use safe-operator ?
<img mat-card-image [src]="spaceScreen?.img">

Related

Angular: display unicode characters from API text in innerHTML

API :
{
"id": 1,
"text": "<p>\r\n \\u2022\r\n Lorem ipsum dolor sit amet, consectetur adipiscing elit: <br />\r\n sed do eiusmod <br />\r\n tempor incididunt ut <br />\r\n labore et dolore magna aliqua\r\n</p>\r\n<p>\r\n \\u2022\r\n </p>"
}
HTML :
<div [innerHTML]="agreementData.text"></div>
when I try to display like this Unicode characters like \u2022 display same as \u2022, it doesn't convert in anything, I cant change API I need to handle requests like this
found solution
pipe:
#Pipe({
name: 'unicodeStringFormat',
})
export class UnicodeFormatPipe implements PipeTransform {
transform(value: any, args?: any): any {
return value.replace(/\\u[\dA-Fa-f]{4}/g, match => {
return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16));
});;
}
}
HTML:
<div [innerHTML]="agreementData.text | unicodeStringFormat"></div>

Pass complete html page to method in ts file angular

I have a group for one module example login. This group contains module.ts, html, spec.ts and page.ts.
I have to write one function in page.ts which will have parameter as a complete HTML page. So I have to write something like this.
func replacingHTMLPlaceHolde(<pass html page here>) <return same html page after replacing>:{}
How can I do this? I have to call this function from ionViewDidEnter() method.
One option I see you could go with is use the server-side html as a string, and use a pipe to replace as you need.
So something along this example (of course, replace what's needed for your own use case):
your-component.ts
export class YourComponent {
public serverHtml: string =
"<div><h2>Block 1</h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div><div><h2>Block 2</h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>";
}
your-component.html
<div [innerHTML]="serverHtml | replacePlaceHolder"></div>
replace-placeholder.pipe.ts
import { Pipe } from "#angular/core";
#Pipe({ name: "replacePlaceHolder" })
export class ReplacePlaceHolderPipe {
transform(value: string): string {
return value.replaceAll("ipsum", "ipsos");
}
}

mongo input name saved as a String

when I use console.log(req.body). It says
{
'hero[title]': 'Lorem ipsum <br> Dolor sit amet.',
'hero[description]': 'Dolor sit amet',
uploadon: 'blahblah'
}
but it should look like:
{
hero[title]: 'Lorem ipsum <br> Dolor sit amet.',
hero[description]: 'Dolor sit amet',
uploadon: 'blahblah'
}
do you know the problem?
My HTML looks like:
<div class="field">
<label for="hero[title]">Titel</label>
<input name="hero[title]" type="text">
</div>
<div class="field">
<label for="hero[description]">Beschreibung</label>
<textarea name="hero[description]" id="" cols="20" rows="5"></textarea>
</div>
UPDATE:
my Mongoose Model is:
var mongoose = require('mongoose');
var heroSchema = new mongoose.Schema({
title: String,
description: String,
image: String
});
module.exports = mongoose.model("Hero", heroSchema);
And this is my Route:
app.post("/dashboard/hero", function(req, res) {
Hero.create(req.body, function(err, newlyAdded){
if(err){
console.log(err);
} else {
console.log(newlyAdded);
res.redirect("/dashboard/hero");
}
});
});
I want to embed it into an ejs file.
hero[title] will try to access a variable stored in title and look up a property with it's value in a hero object - which is going to break. That is why it is correctly represented as a string like 'hero[title]' when your request body was parsed to JS object.

React Js axios returns empty div before actual data

I'm working on a simple app, where info from JSON should be added on a page. I was able to fetch data from a local JSON file using Axios and display it. The problem is that app renders an empty array(of the selected data) first, and only after that the actual data itself.
local json file:
{
"home": [
{
"id": "app",
"management": [
{
"id": "image",
"alt": "truck",
"img": "./img/assets/img.png",
"img2": "./img/assets/img2.png",
"img3": "./img/assets/img3.png"
},
{
"id": "services",
"title": "Managementt",
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur."
}
]
}
]
My code to fetch data from local JSON is:
const [services, setServices] = useState([]);
const getServices = async () => {
const response = await axios.get("./home.json");
setServices(response.data.home[2].management);
console.log(response);
};
useEffect(() => {
getServices();
}, []);
then it gets displayed using this code:
return (
<>
<Layout>
{services.map(({
img,
img2,
img3,
id,
title,
text,
}) => (
<>
<div className={styles.flex}>
{id === "image" ? (
<img
id={id}
className={styles.logo}
srcSet={`${img2} 2x,
${img3} 3x`}
alt={alt}
src={img}
/>
) : null}
</div>
<div>
{id === "services" ? (
<div className={styles.services} key={id}>
<div style={{ display: "flex" }}>
<h1 className={styles.text}>{title}</h1>
<p>{text}</p>
</div>
) : null}
</div>
</div>
</>
)
)}
</Layout>
</>
What happens is before actual image/text gets displayed, the app renders an empty div that can bee seen in console.log(has the same className and parameters as the rendered data, for example, if text's div has a width of 400px, next to the image there is an empty div with 400px width also) and it's messing up all styles. I want to display image and the text as flex(next to each other on the page), but when I use display flex, text's empty array displays first and takes the space near the image, and the actual text gets displayed below the image.
Please see a link to the image how I want to style text and image flex image-text
I also have to specify the id of the element, otherwise all the images from json file will be rendered.
Any suggestions will be appreciated greatly. Thank you
you have to ckeck before rendering that data exists or not like this
if(services.length>0)
{
return (
<>
<Layout>
{services.map(({
img,
img2,
img3,
id,
title,
text,
}) => (
<>
<div className={styles.flex}>
{id === "image" ? (
<img
id={id}
className={styles.logo}
srcSet={`${img2} 2x,
${img3} 3x`}
alt={alt}
src={img}
/>
) : null}
</div>
<div>
{id === "services" ? (
<div className={styles.services} key={id}>
<div style={{ display: "flex" }}>
<h1 className={styles.text}>{title}</h1>
<p>{text}</p>
</div>
) : null}
</div>
</div>
</>
)
)}
</Layout>
</>
}
else{
return <div> Loading...</div>
}

Angular 6 *ngFor not updating view

I am using material card to get populated using *ngFor but it does not show binding
it shows this in the DOM ,but when I console my binded variable, it shows the value but still my mat-card not get re populated.
NOTE :-- when I click on any form field box its then changed to <!--bindings={
"ng-reflect-ng-for-of": "[object Object],[object Object"
}--> this and data starts showing
Below is my code
<mat-card class="inner-list-card" *ngFor="let uglist of userGroupViewModel.UserGroupList"
(click)="getDetails(uglist['groupId'],$event)" routerLink="scope">
<div class="inner-card">
<li class="pointer">
<span class="listIcon">
<i class="fa fa-users"></i>
</span>
<a class="textwrap">
{{ uglist.groupName }}
<small class="listDate">Last Updated: {{ uglist.updatedOn*1000 | date }}</small>
</a>
<span>
<a class="protected">
<img alt="" src="assets/protected.png" height="25px" width="23px">
</a>
</span>
</li>
</div>
<div class="desc"> {{ uglist.description }}</div>
<div class="routing-element">Show
More
<i class="fa fa-angle-right alignRight" aria-hidden="true"></i>
</div>
</mat-card>
and I went through the below reference links:
angular2 ngFor not working while fetching data from api on ngOnInit()
Welcome to asynchronous programming :)
You have not included the details of how you're getting the data from your api... what i have done is used observable to which i subscribed. As soon as the data is available, the *ngFor renders the result for us.
relevant service.ts:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root',
})
export class MyService {
apiURL: string = 'https://ddxhruyrrj.execute-api.us-east-2.amazonaws.com/aiProd/projectslazy';
constructor(private http: HttpClient) { }
getData() {
return this.http.get(this.apiURL);
}
}
relevant component.ts:
export class CardFancyExample {
dataSet:any;
constructor(private serv: MyService) {
this.serv.getData().subscribe(
dataa => { console.log(dataa); this.dataSet = dataa; }
, errr => { console.log(errr); }
)
}
}
relevant html:
<div *ngIf="dataSet== ''">
No data loaded
</div>
<div *ngIf="dataSet != ''">
<mat-card class="example-card" *ngFor="let data of dataSet">
<mat-card-header>
<mat-card-title>{{data?.project}}</mat-card-title>
<mat-card-subtitle>{{data?.role}}</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.akberiqbal.com/JumboMob.jpg" alt="Akber Iqbal">
<mat-card-content>
<p>
{{data?.description}}
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
</div>
complete working stackblitz here