PDF doesn't show any data - lwc

when I press "Generate PDF" it shows only the Column Headings
Please help me. The codes are as follows
HTML:
<template>
<lightning-button onclick={generateData} label="Generate PDF"></lightning-button>
</template>
//JS Code
contactList doesn't show any data
But when I check in the class, it does retrieve contacts
My code should return all the contacts regardless of Account
I am checking whether data retrieve or not
import { LightningElement, track, wire, api } from "lwc";
import{loadScript} from "lightning/platformResourceLoader";
import JSPDF from '#salesforce/resourceUrl/jspdf';
import getContacts from '#salesforce/apex/Pdfgenerator.getContactsController';
export default class JspdfDemo extends LightningElement {
#api recordId;
#track data;
#track error;
#wire(getContacts, {appId: '$recordId'})
contactList;
get responseReceived(){
if (this.contactList=true){
console.log("Contacts is " +this.contactList);
return true;
}
else
console.log("Contacts has NO Data");
return false;
}
headers = this.createHeaders([
"Id",
"FirstName",
"LastName"
]);
renderedCallback(){
Promise.all([
loadScript(this, JSPDF)
]);
}
generatePdf(){
const {jsPDF}= window.jspdf;
const doc = new jsPDF;
doc.table(30, 30, this.contactList, this.headers, {autosize:true});
doc.save("demo.pdf");
console.log("pdf is " +this.contactList);
}
generateData(){
console.log('Record ID is:'+this.recordId);
this.generatePdf();
//console.log('Contacts are : after generatePdf:'+this.contactList);
}
createHeaders(keys){
let result = [];
for (let i=0; i<keys.length; i += 1){
result.push({
id: keys[i],
name: keys[i],
prompt: keys[i],
width: 65,
align: "center",
padding: 0
});
}
return result;
}
}
//Class:
public with sharing class PdfGenerator {
#AuraEnabled(cacheable=true)
public static List<Contact> getContactsController(){
List<Contact> con=new List<Contact>();
con = [SELECT Id, FirstName, LastName FROM Contact WITH SECURITY_ENFORCED];
system.debug('Data from Class is :'+con);
return con;
}
}

Related

Uncaught (in promise) TypeError: hobbies is not iterable at createHobby when using Prisma and Postgresql

So I'm very new to Prisma, and actually also to React. My Postgresql database works, but I'm trying to show the stored data in my application. My very simple table in the schema file looks like this:
model Hobby {
id Int #id #default(autoincrement())
title String
}
I'm using useContext to distribute my createHobby functionality, this is what the context file looks like.
export async function getServerSideProps() {
const hobbies: Prisma.HobbyUncheckedCreateInput[] = await prisma.hobby.findMany();
return {
props: {initialHobbies: hobbies},
};
}
export const HobbyContext = createContext({})
function Provider({ children, initialHobbies }){
const [hobbies, setHobbies] = useState<Prisma.HobbyUncheckedCreateInput[]>(initialHobbies);
const createHobby = async (title) => {
const body: Prisma.HobbyCreateInput = {
title,
};
await fetcher("/api/create-hobby", {hobby : body});
console.log(hobbies);
const updatedHobbies = [
...hobbies,
body
];
setHobbies(updatedHobbies);
const contextData = {
hobbies,
createHobby,
}
return (
<HobbyContext.Provider value={contextData}>
{children}
</HobbyContext.Provider>
);
};
export default HobbyContext;
export {Provider};
Here I get the following error Uncaught (in promise) TypeError: hobbies is not iterable at createHobby. Which refers to the const updatedHobbies = [...hobbies, body];
For more context, I have a HobbyCreate.tsx which creates a little hobby card that renders the title of the hobby, which is submitted with a form.
function HobbyCreate({updateModalState}) {
const [title, setTitle] = useState('');
const {createHobby} = useHobbiesContext();
const handleChange = (event) => {
setTitle(event.target.value)
};
const handleSubmit = (event) => {
event.preventDefault();
createHobby(title);
};
return (
...
<form onSubmit={handleSubmit}></form>
...
)
I can't really figure out what is going wrong, I assume somewhere when creating the const [hobbies, setHobbies] and using the initialHobbies.
I don't think you're using the Context API correctly. I've written working code to try and show you how to use it.
Fully typed hobby provider implementation
This is a fully typed implementation of your Provider:
import { createContext, useState } from 'react';
import type { Prisma } from '#prisma/client';
import fetcher from 'path/to/fetcher';
export type HobbyContextData = {
hobbies: Prisma.HobbyCreateInput[]
createHobby: (title: string) => void
};
// you could provide a meaningful default value here (instead of {})
const HobbyContext = createContext<HobbyContextData>({} as any);
export type HobbyProviderProps = React.PropsWithChildren<{
initialHobbies: Prisma.HobbyCreateInput[]
}>;
function HobbyProvider({ initialHobbies, children }: HobbyProviderProps) {
const [hobbies, setHobbies] = useState<Prisma.HobbyCreateInput[]>(initialHobbies);
const createHobby = async (title: string) => {
const newHobby: Prisma.HobbyCreateInput = {
title,
};
await fetcher("/api/create-hobby", { hobby: newHobby });
console.log(hobbies);
setHobbies((hobbies) => ([
...hobbies,
newHobby,
]));
};
const contextData: HobbyContextData = {
hobbies,
createHobby,
};
return (
<HobbyContext.Provider value={contextData}>
{children}
</HobbyContext.Provider>
);
}
export default HobbyContext;
export { HobbyProvider };
Using HobbyProvider
You can use HobbyProvider to provide access to HobbyContext for every component wrapped inside it.
For example, to use it in every component on /pages/hobbies your implementation would look like:
// /pages/hobbies.tsx
import { useContext, useState } from 'react';
import HobbyContext, { HobbyProvider } from 'path/to/hobbycontext';
export default function HobbiesPage() {
// wrapping the entire page in the `HobbyProvider`
return (
<HobbyProvider initialHobbies={[{ title: 'example hobby' }]}>
<ExampleComponent />
{/* page content */}
</HobbyProvider>
);
}
function ExampleComponent() {
const { hobbies, createHobby } = useContext(HobbyContext);
const [title, setTitle] = useState('');
return (
<div>
hobbies: {JSON.stringify(hobbies)}
<div>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<button onClick={() => createHobby(title)}>Create hobby</button>
</div>
</div>
);
}
Similarly, to make the context available throughout your entire website, you can use HobbyProvider in
/pages/_app.tsx.
Using getServerSideProps
To retrieve the initialHobbies from the database, your getServerSideProps would look something like this:
// /pages/hobbies.tsx
import type { Hobby } from '#prisma/client';
export async function getServerSideProps() {
// note: there is no need to use `Hobby[]` as prisma will automatically give you the correct return
// type depending on your query
const initialHobbies: Hobby[] = await prisma.hobby.findMany();
return {
props: {
initialHobbies,
},
};
}
You would have to update your page component to receive the props from getServerSideProps and set initialHobbies on HobbyProvider:
// /pages/hobbies.tsx
import type { InferGetServerSidePropsType } from 'next';
export default function HobbiesPage({ initialHobbies }: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<HobbyProvider initialHobbies={initialHobbies}>
<ExampleComponent />
</HobbyProvider>
);
}
Note your page component and getServerSideProps function have to be exported from the same file

How to access an object property inside a function that's inside a class

I was trying to fetch the ID that has been created from a new class to use it as a data key, but I can't seem to be able to access it. How can be able to do so, kindly help.
My code has a class and a function that uses the class to create a new item and append it onto a main container in my html file.
I want to use the setAttribute method to add a data-key and link the ID that has been created by the function createProjectItem() in the class but it says that the new class(newProject) has not been defined.
class NewProject {
constructor(title) {
this.title = title;
}
createProjectItem() {
const projectArray = {
title: this.title,
id: Date.now(),
//ID TO BE ACCESSED ↑↑
};
projectArrayList.push(projectArray)
console.log(projectArrayList);
}
}
const createProjectList = document.querySelector(".create-projectList");
export default function createProjectFromClass() {
createProjectList.addEventListener("click",() => {
//Creates new class
const Titleinput = document.getElementById("project-title");
const titleText = Titleinput.value.trim();
if (titleText !== "") {
const newProject = new NewProject(titleText);
newProject.createProjectItem()
console.log(newProject.id);
Titleinput.value = "";
}
//Append new class to projects list
function appendProject() {
const container = document.querySelector(".projects");
const createProject = document.querySelector(".create-project")
const projectList = document.createElement("div");
projectList.setAttribute("class","project-list project-dynamic");
projectList.setAttribute("data-key",newProject.id)
//DATA KEY TO FETCH ID FROM NEW CLASS ↑↑
projectList.innerHTML = `
<p>Project name</p>
<i class="fa-solid fa-trash-can"></i>
`
container.insertBefore(projectList,createProject);
}
appendProject()
})
}
I access the property
let projectArrayList = [];
class NewProject {
constructor(title) {
this.title = title;
}
createProjectItem() {
const projectArray = {
title: this.title,
id: Date.now(),
};
projectArrayList.push(projectArray)
console.log(projectArrayList);
}
}
export default function createProjectFromClass() {
createProjectList.addEventListener("click",() => {
// Create a new project from project class
const Titleinput = document.getElementById("project-title");
const titleText = Titleinput.value.trim();
if (titleText !== "") {
const newProject = new NewProject(titleText);
newProject.createProjectItem()
console.log(newProject.id);
Titleinput.value = "";
}
//Append newProject to projects list
function appendProject() {
const container = document.querySelector(".projects");
const createProject = document.querySelector(".create-project")
const projectList = document.createElement("div");
projectList.setAttribute("class","project-list project-dynamic");
projectList.setAttribute("data-key","?????")
projectList.innerHTML = `
<p>Project name</p>
<i class="fa-solid fa-trash-can"></i>
`
container.insertBefore(projectList,createProject);
}
appendProject()
})
}

WebApi with Axios

Goal:
Use Axios with put and post method from react TS to Backend WebApi c#.
Problem:
The code doesn't work in relation to CORS.
What part from the backend source code am I missing in order to make backend to retrieve data that is PUT or POST?
Thank you!
React TS
import React from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
function App() {
const get = () => {
axios.get("https://localhost:7177/WeatherForecast/GetTestData")
.then(
response => console.log(response)
);
};
const update = () => {
const data =
{
CandyNumber: Number("1"),
Name: "asdf"
};
axios.put("https://localhost:7177/WeatherForecast/UpdateTestData", data)
.then(
response => console.log(response)
);
};
const add = () => {
const data =
{
CandyNumber: Number("1"),
content: "asdf"
};
axios.post("https://localhost:7177/WeatherForecast/AddTestData", data)
.then(
response => console.log(response)
);
};
return (
Get
Add
Uppdate
);
}
export default App;
backend
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace WebTest2.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet("GetTestData", Name = "GetTestData")]
[ProducesResponseType(typeof(List<Test>), StatusCodes.Status200OK)]
[ProducesResponseType(204)]
[Produces("application/json")]
public async Task<IActionResult> GetTestData()
{
List<Test> mytest = new List<Test>();
Test myTest = new Test()
{
CandyNumber = 1,
Name = "asdf"
};
Test myTest2 = new Test()
{
CandyNumber = 2,
Name = "asdf"
};
mytest.Add(myTest);
mytest.Add(myTest2);
return Ok(mytest);
}
[HttpPost("AddTestdata", Name = "AddTestdata")]
public async Task<IActionResult> AddTestdata(Test test)
{
List<Test> mytest = new List<Test>();
Test myTest = new Test()
{
CandyNumber = 1,
Name = "asdf"
};
Test myTest2 = new Test()
{
CandyNumber = 2,
Name = "asdf"
};
mytest.Add(myTest);
mytest.Add(myTest2);
return StatusCode(StatusCodes.Status204NoContent, null);
}
[HttpPut("UpdateTestdata", Name = "UpdateTestdata")]
public async Task<IActionResult> UpdateTestdata(Test test)
{
return StatusCode(StatusCodes.Status204NoContent, null);
}
}
public class Test
{
public int CandyNumber { get; set; }
public string Name { get; set; }
}
}
Program.cs
using Microsoft.OpenApi.Models;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = ""
});
});
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAllHeaders",
corsbuilder =>
{
corsbuilder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("http://localhost:3000/");
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//--
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Add
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true) // allow any origin
.AllowCredentials()); // allow credentials
after " app.UseSwaggerUI();"

Trying to redirect user on valid contact form submission

Hi so I'm trying to make my page redirect to 'confirmationpage.html' only when all the fields are correctly entered. This is my Javascript, how would I go about doing this?
const form = document.getElementById('form');
const name = document.getElementById('name');
const email = document.getElementById('email');
const subject = document.getElementById('subject');
const text = document.getElementById('text');
form.addEventListener('submit', function(e) {
e.preventDefault();
checkInputs();
});
function checkInputs() {
// get values from the inputs
const nameValue = name.value.trim();
const emailValue = email.value.trim();
const subjectValue = subject.value.trim();
const textValue = text.value.trim();
if(nameValue === '') {
// show error message
// add error class
setErrorFor(name, 'Name cannot be blank');
} else {
// add success class
setSuccessFor(name);
}
if(emailValue === '') {
setErrorFor(email, 'Email cannot be blank');
} else if(!isEmail(emailValue)) {
setErrorFor(email, 'Please enter a valid email address');
} else {
setSuccessFor(email);
}
if(subjectValue === '') {
setErrorFor(subject, 'A subject is required');
} else {
setSuccessFor(subject);
}
if(textValue === '') {
setErrorFor(text, 'Please add some text');
} else {
setSuccessFor(text);
}
}
function setErrorFor(input, message) {
const formControl = input.parentElement; // .form-control
const small = formControl.querySelector('small');
// add error message
small.innerText = message;
// add error class
formControl.className = 'form-control error';
}
function setSuccessFor(input) {
const formControl = input.parentElement;
formControl.className = 'form-control success';
}
function isEmail(email) {
return /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*.test(email);
}
Any help would be very appreciated! I'm very new to webpage design and I've been struggling a lot recently

Render page in custom HttpExceptionFilter

Does anybody can suggest solution, how to render page in custom HttpExceptionFilter in nest.js, when using Fastify and ejs.
Below current HttpExceptionFilter:
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '#nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response: FastifyReply<any> = ctx.getResponse();
const request: FastifyRequest = ctx.getRequest();
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
const objResponse = Object.assign(exception, {
timestamp: new Date().toISOString(),
path: request.req.url
});
if (status === HttpStatus.UNAUTHORIZED)
return // page render with some content;
if (status === HttpStatus.NOT_FOUND)
return // page render with some content;
if (status === HttpStatus.INTERNAL_SERVER_ERROR) {
if (process.env.NODE_ENV === 'production') {
return // page render with some content;
}
else {
return response.status(status).send(objResponse);
}
}
}
}