Missing single quote while exporting pdf using Kendo react - PDFExport - kendo-react-ui

Are you ready to refill your bottles?
Yes - I’m ready
Would you like to talk to the specialist?
No, I m all set!
const dynamic_question = props.oResponse.filter((item: any) => item.dynamic_question_status === true);
const CommonTrimming = (props: { value: string }) => {
let temp = props.value
.replace(/{*/g, '')
.replace(/}*/g, '')
.replaceAll(/'*/g, '')
.replace(/&/g, '&')
.replaceAll('\\n', '<br/>')
.replaceAll(',', '<br/>');
console.warn("executing or not ? ", temp);
return <div dangerouslySetInnerHTML={{ __html: temp }}></div>;
};
`
i have used to make common trimming.
here in second example we're missing single quote.
it should come in downloaded pdf.

Related

TypeError: Cannot read property 'count' of undefined

I am a novice MERN stack developer.
I am trying to calculate the number of pages for pagination. The info object prints in console.log. However, when I try to use it in the for loop I get an error.
Can someone please explain what's the React logic or flow behind this? I have had issues with this multiple times but, could fix it with conditional rendering. But, somehow I wasn't able to fix this and I don't seem to understand the logic of how the flow in react is.
App Component :
const App = () => {
const [episodes, setEpisodes] = useState({});
const [loading, setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [episodesPerPage, setEpisodesPerPage] = useState(10);
useEffect(() => {
const fetchEpisodes = async () => {
setLoading(true);
const res = await axios.get('https://rickandmortyapi.com/api/episode/');
setEpisodes(res.data);
setLoading(false);
};
fetchEpisodes();
}, []);
console.log(episodes.info);
return (
<div>
<div id='header'>
<h1>Rick & Morty</h1>
<h2>Episodes</h2>
</div>
<div>
<h3>All Episodes</h3>
<EpisodeList episodeList={episodes.results} loading={loading} />
<Pagenation info={episodes.info} />
</div>
</div>
);
};
export default App;
Pagenation Component:
const Pagenation = ({ info }) => {
const pageNumbers = [];
console.log(info);
for (let i = 1; i <= Math.ceil(info.count / 20); i++) {
pageNumbers.push(i);
}
return (
<nav aria-label='...'>
<ul class='pagination pagination-lg'>
{pageNumbers.map((number) => {
return (
<li class='page-item active' aria-current='page'>
<span class='page-link'>
{number}
<span class='sr-only'>(current)</span>
</span>
</li>
);
})}
</ul>
</nav>
);
};
Conditional rendering can be the solution here as well.
episodes is initially an empty object, so episodes.info is initially undefined. This means you cannot access a property on info without checking if it exists first because you know already that it will be undefined at the beginning.
A simple solution might look like this:
{episodes.info && <Pagenation info={episodes.info} />}
You could also move the conditional into the Pagenation component to be something like this:
if (info) {
for (let i = 1; i <= Math.ceil(info.count / 20); i++) {
pageNumbers.push(i);
}
}
Regardless of your strategy to avoid the error, the core of the issue is that you have data that is loaded after the component mounts. This means you need to account for that data being missing for at least one render.

How to format <td> value in angular dynamic table

am trying to format displayed value in an angular table
this is my table right now
instead of showing the link am trying to format the displayed content link
instead of https://www.udemy.com/course/amazon-alexa-101-publishing-alexa-skills-without-coding/
am trying to show [amazon alexa 101 publishing alexa skills without coding]
i have tried in nodejs
var url = require('url');
var adr ='https://www.udemy.com/course/technology-strategy-success/?couponCode=05DIwC2320';
var q = url.parse(adr, true);
var data = q.pathname.replace("/course/", '');
var output = data.replace("/", '');
console.log(output);
this is my ts file
import {Component, OnDestroy, OnInit} from '#angular/core';
import {ApiService} from '../../services/api.service';
#Component({
selector: 'app-data',
templateUrl: './data.component.html',
styleUrls: ['./data.component.css']
})
export class DataComponent implements OnInit{
udemydata = [];
constructor(private apiService: ApiService) {
}
ngOnInit() {
this.apiService.getCoupen().subscribe((data: any[]) => {
this.udemydata = data;
console.log(data);
},
error => {
console.log('err', error);
}
);
}
}
this is my component.html file
<table datatable [dtOptions]="dtOptions" class="table align-items-center table-flush">
<thead>
<tr>
<th scope="col">S.No</th>
<th scope="col">course</th>
<th scope="col">Link</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of udemydata; let i = index;">
<td>{{i+1}}</td>
<td>{{data["courseidhref"]}}</td>
<td><a href ="{{data['courseidhref']}}" target="_blank"><button class="btn btn-icon btn-3 btn-primary" type="button">
<span class="btn-inner--icon"><i class="ni ni-send"></i></span>
<span class="btn-inner--text">Enroll Now</span>
</button></a></td>
</tbody>
</table>
First of all, note that Angular runs in user's browser, so you want to use the URL class, instead of Node's url module, as that is only available in Node runtime.
The, we can break down the process into a few steps:
const url = 'https://www.udemy.com/course/technology-strategy-success/?couponCode=05DIwC2320';
// first, convert to URL class so that it can do the parsing for us.
const parsedUrl = new URL(url);
// we want to ignore the host and query string, so we only need the pathname, as you have yourself discovered.
const pathName = parsedUrl.pathname;
// then, let's split the pathname on any "/" characters.
const urlParts = pathName.split('/');
// this produces some empty strings, so let's get rid of them
const nonEmptyParts = urlParts.filter(x => x !== '');
// now we are left with proper url parts.
// In our case: [ "course", "technology-strategy-success" ]
// Assuming that the last element is always the course name:
const coursePart = nonEmptyParts.pop(); // or, nonEmptyParts[nonEmptyParts.length - 1]
// Finally, let's get rid of the hyphens, replacing them with spaces.
// The regex has two parts:
// 1. /-/ stands for match hyphens
// 2. g stands for "global" - we want to replace ALL hyphens, not just the first one
const courseName = coursePart.replace(/-/g, ' ');
If you want to add a bit more sugar, you could also change the first letter of the course title to be a capital.
const title = courseName[0].toUpperCase() + courseName.slice(1);
// Technology strategy success
If you want to capitalize every word:
const title = courseName.split(' ')
.map(word => word[0].toUpperCase() + word.slice(1))
.join(' ');
// Technology Strategy Success
Now, to show it in Angular you could go about it in a few ways:
After you receive the data from your service, convert it so that the data also has the course title.
Create a method in your component that converts url to course title and call it in the template: <td>{{convertHrefToTitle(data.courseidhref)}}</td>
Create a courseTitle Pipe that transforms hrefs to titles. You would use it like so:
<td>{{data.courseidhref | courseTitle}}</td>
Option 1 is fairly simple. When we get the data, we transform it once.
Option 2 is very simple too, but the function will run VERY frequently, on every change detection cycle. This might affect performance if used without thinking.
Option 3 is slightly more complicated, but it will NOT run on change detection cycle unless the href itself has changed. Read more about pipes ion official docs.
Here's an example of how to use Option 1:
Given interfaces
interface OriginalData {
courseidhref: string;
}
interface TransformedData {
courseidhref: string;
title: string;
}
transformData(data: OriginalData ): TransformedData {
return {...data, title: this.hrefToTitle(data.courseidhref)}
}
hrefToTitle(href: string): string {
// paste the solution from above into here
}
ngOnInit() {
this.apiService.getCoupen().subscribe((data: any[]) => {
const transformedData = data.map(course => this.transformData(course));
this.udemydata = transformedData;
console.log(data, transformedData);
},
error => {
console.log('err', error);
}
);
}
Finally, in your template you can do
<td>{{data.title}}</td>
<td><a href ="{{data.courseidhref}}" target="_blank">...

Why me subscribe method in angular is not working?

I'm new in Angular, Nodejs and I was doing a CRUD app of txt files
I have to list all the files in a list, if you click one file need to display the data on a 'P'aragraph
My document component
getDocuments() - returns an array of all files in a path
getOneDOcument(name) -> get all the data of a file given "name"
getData(name) -> have to send the data to the paragraph with the id _> "paragraph_content"
getDocuments(){
this.DocumentService.getDocuments()
.subscribe(res => {
this.DocumentService.documents = res as Document[]
console.log("dentro del susbcribe");
console.log(res);
});
console.log("Fuera del subscribe");
}
getOneDocument(name : String){
console.log("NOO");
this.DocumentService.getOneDocument(name).subscribe(res => {
this.DocumentService.documentSelected = res as Document;
console.log(".");
});
}
getData(name : String){
console.log("hello name -> " , name)
// document.getElementById("paragraph_content").innerHTML = this.DocumentService.getOneDocument(name)
console.log("Before the subscrie");
this.DocumentService.getOneDocument(name)
.subscribe( (res ) =>{
//I need to change the paragraph content like this
//document.getElementById("paragraph_content").innerHTML = res.toString() Not working
console.log("Within", res);
} )
console.log("After Subscribe ")
}
Document Service
I got the arrays of the url given
getDocuments(){
console.log("Get Documents method");
return this.http.get(this.URL_API );
}
getOneDocument(name: String){
console.log("Get OneDocyment method name given: " , name);
return this.http.get(this.URL_API + `/${name}`)
}
postDocument(){
//left
}
deleteDocument(name:String){
//left
}
Document Component html
<nav>
<ul class="ds-list-unstyled" *ngFor="let document of DocumentService.documents">
<li> {{document}} </li>
</ul>
</nav>
<article>
<h2>Texto en pantalla: </h2>
<p id="paragraph_content">Needs to change with a click
</p>
</article>
And the responde that I got when I click a file is:
Thanks in advance
The XMLHttpRequest property responseType is an enumerated string value specifying the type of data contained in the response. It also lets the author change the response type.
You should set the responseType to text.
Try like this
getOneDocument(name: String){
console.log("Get OneDocyment method name given: " , name);
const requestOptions: Object = {
responseType: 'text'
}
return this.http.get(`${this.URL_API}/${name}`,requestOptions )
}
I think you problem is that you are not specifying that the data is text, that is why is trying to convert to JSON.
Try adding the responseType to the request, something like this,
getOneDocument(name: String){
return this.http.get(`${this.URL_API}/${name}`, {responseType: 'text'})
}

Show the item hit content only when the search box is not empty

I have this in my algolia file for my jekyll site.
<script>
const search = instantsearch({
appId: '{{ site.algolia.application_id }}',
apiKey: '{{ site.algolia.search_only_api_key }}',
indexName: '{{ site.algolia.index_name }}',
searchParameters: {
restrictSearchableAttributes: [
'title',
'content'
],
facetFilters: ['type:post']
},
});
const hitTemplate = function(hit) {
let date = '';
if (hit.date) {
date = moment.unix(hit.date).format('L');
// date = moment.unix(hit.date).format('MMM Do YY');
modifiedDate = moment.unix(hit.last_modified_at).format('MMM Do YY');
}
const url = hit.url;
const title = hit._highlightResult.title.value;
const content = hit._highlightResult.html.value;
return `
<div class="post-list">
<span class="post-date-list-wrap">
<span class="post-date-list">${date}
<span class="post-title"> ${title} </span>
</span>
${content}
</div>
`;
}
const hitTemplateTrans = function(hit) {
let date = '';
if (hit.date) {
date = moment.unix(hit.date).format('MMM DD YYYY');
}
const url = hit.url;
const title = hit._highlightResult.title.value;
const content = hit._highlightResult.html.value;
return `
<div class="post-list">
<span class="post-date-list-wrap">
<span class="post-date-list">${date}
<span class="post-title"> ${title}</span>
</span>
</span>
</div>
`;
}
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-searchbar',
placeholder: 'search notes',
autofocus: true
})
);
search.addWidget(
instantsearch.widgets.hits({
container: '#search-hits',
templates: {
empty: 'No results',
item: hitTemplate
},
})
);
search.start();
</script>
Without typing anything in the search box I have the list of articles
with the excerpt, the short introduction of the article.
That's because I have ${content} to show the highlights when someone
types the search term.
That's fine and everything is working but... I don't want to show the contents of each item when the search box is empty.
If the search box is empty I would like to keep only the title and the date
but if the search box is not empty just show the title/date and the excerpt as it's usual.
It seems like an easy task but I'm stuck right now, I tried removed the content tag and put in the hit transformation function, but it doesn't work.
The instantsearch.js library has a function hook, called searchFunction, you can define when instanciating the library. That is called right before any search is performed. You can use it to check if the current query is empty or not, and adapt your layout based on this knowledge.
Here is a slightly edited script (irrelevant parts removed) that should let you do what you're looking for:
let additionalClass = '';
const search = instantsearch({
[…]
searchFunction: function(helper) {
if (helper.getState().query === '') {
additionalClass = 'post-item__empty-query';
} else {
additionalClass = '';
}
helper.search()
}
});
[…]
const hitTemplate = function(hit) {
return
`<div class="post-item ${additionalClass}">
[…]
</div>`
;
}
.post-item__empty-query .post-snippet {
display: none;
}
What it does is defining a global variable (additionalClass) that will be used in the hit template (added alongside item-post, at the root level).
Right before everysearch, we check if the query is empty. If so, we set additionalClass to item-post__empty_query. We also defined in CSS that when this class is applied, the content should be hidden.
All of that together makes the title + date displayed when no search is performed, and the content displayed only when an actual keyword is searched for.
Hope that helps,

Cant send non-english characters to PDF

I am having trouble rendering non-english characters in a pdf that gets generated as a blob using node.js and displayed in an iframe element.
First line and client Name is supposed to be cyrillic characters I am using fluentreports which mentions nothing about the character set that it can handle. Here is the code that receives the blob from my server.
if (xhr.status === 200) {
var file = new Blob([xhr.response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
this.setState({
pdf: fileURL
})
}
});
xhr.send(formDataString);
}
render() {
return (
<div>
<div style = {{ margin: '0'}} className = "container">
<div className= "jumbotron">
{this.state.form ? <DateForm onChange = {this.handleChange} onChange2 = {this.handleChange2} onSubmit = {this.onSubmit} date1 = {this.state.date1} date2 = {this.state.date2}/> : null}
{this.state.pdf? <iframe style = {{width:"100%" ,height: "800"}} src = {this.state.pdf}> </iframe> : null}
</div>
</div>
</div>
);
}
To answer my own question and hopefully help someone else. Fluentreports allows to register fonts. I am generating my pdf on the server side so here is what needs to be done. Download Arial Unicode MS and from a static point, serve it to the location where you render your report as follows.
// Create a Report
var rpt = new Report(res,({fontSize: 10,font: 'Bulgarian'}))
.titleHeader(hh)
.margins(40)
.data( {}) // Add some Data (This is required)
rpt.registerFont("Bulgarian", {normal: './server/static/ARIALUNI.ttf'});

Resources