Angular: display unicode characters from API text in innerHTML - html

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>

Related

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");
}
}

TYPO3 render full t3:// links from bodytext in utility files

I have a headless TYPO3 installation and i need to render all the content elements as json. So far so good. The only problem i have right now is to replace the t3:// links with the full URLs since i do not have the frontend to take care of it. So the question is:
How do i replace the intern TYPO3 links in a bodytext (RTE) to full URLs?
I have tried the following but it dint really help:
$cObj->stdWrap_HTMLparser($element['bodytext']
Best regards
So i examined the TYPO3\CMS\Fluid\ViewHelpers\Format\HtmlViewHelper to get some ideas. It is actually very easy to do it.
Note: I have only tested this with t3://page?uid= and it works. The moment i find other use cases as well, i will update this answer
This code happens on my Utility class under the my_ext/Classes/Utility/MyUtility.
I first inject the TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer with DI (Dependency Injection)
/**
* #var ContentObjectRenderer
*/
protected ContentObjectRenderer $cObj;
/**
* #param ContentObjectRenderer $cObj
*/
public function __construct(
ContentObjectRenderer $cObj
) {
$this->cObj = $cObj;
}
Now i can use the parseFunc function to replace the links, with full URls (without the base url). BUT we have to define what kind of reference this function will get, which in my case would be the lib.parseFunc. So this is how it looks like:
Sometimes you only need the first and second parameters and you can leave the reference empty. You have to experiment a bit and make it work according to your needs.
public function my_module(array $teaserHomepage): array
{
$parseFuncTSPath = 'lib.parseFunc';
$newConstructedArray = [];
foreach ($teaserHomepage['fields'] as $element) {
...
$newConstructedArray['fields']['bodytext'] = $this->cObj->parseFunc($element['bodytext'], [], '< ' . $parseFuncTSPath);
}
return $newConstructedArray;
}
The before text:
<p>sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam.</span><br /> <br /> </p>
The after text:
<p>sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam.</span><br> <br> </p>
Hopefully it helped someone
Best regards

Add (click) method to link in text block in Angular component

I have a small problem. I'm getting a text from the server with innerHtml which is inserted in Angular component. Inside of this text, there are possibly some links. Example text block looks like this:
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href="some.link.com">Link<a/>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Is there a way to insert a bind there a click action like this?
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href="some.link.com" (click)="methodName('http://domain.tld/page.html')">Link<a/>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Thanks.
If I get you right, you render html loaded from server with innerHtml, in this case you can't use Angular directives inside of this template. But you can add listeners with common JS (document.addEventListener) after content rendering.
#Component({
template: `<div #wrapper [innerHTML]="sanitizedHtml"></div>`
}) class MyComp {
#ViewChild('wrapper') wrapper: ElementRef<HtmlElement>;
ngAfterViewInit() {
const links = this.wrapper.naviveElement.querySelectorAll('a[href]');
links.forEach(link =>
link.addEventListener('click', this.linkClickHandler.bind(this));
);
}
linkClickHandler(event: MouseEvent) {
...
}
}
For dynamic links you can bind your desired url link in you a tag like the following
<a [href]="some.url">Link</a>
If some is an object.
For click event you can have something like
method(url: string) {
window.location.href = url;
}
then you'll pass your url string like (click)="method('http://domain.tld/page.html')"

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 4: outputing data with *ngFor not working

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">