Hopefuly someone can assist/direct me here.
I'm making use of the webshare API on my site. The site contains an array of posts that will have a share link. This is built using a foreach and all have unique urls to use. I want to add a share button to each of those images. I currently have it working on a singular instance but unable to get it to loop through all the share buttons.
Here is the current script:
const shareButton = document.querySelector('.share-button');
const url = document.querySelector('.post-link a').href;
shareButton.addEventListener('click', event => {
if (navigator.share) {
navigator.share({
title: 'Check out this ad I saw on ...',
url
}).then(() => {
console.log('Shared');
})
.catch(console.error);
}
});
I'm really struggling with how to get it to loop through all share buttons and not just be usable on the first instance.
Apologeis if this is simple.
For a start, you need to add a click listener to all buttons, not just the first. You can do this exclusively when the API is supported, else, you may want to hide the buttons. Here's the modified script (note that you need to get the URL of each post individually, see the comment):
const shareButtons = document.querySelectorAll('.share-button');
if ('share' in navigator) {
shareButtons.forEach((shareButton) => {
shareButton.addEventListener('click', () => {
// Get the URL from the dataset or query the DOM.
const url = shareButton.dataset(url);
navigator.share({
title: 'Check out this ad I saw on ...',
url
}).then(() => {
console.log('Shared');
}).catch(console.error);
});
});
} else {
shareButtons.forEach((shareButton) => {
shareButton.style.display = 'none';
});
}
My code works fine when I write in browser localhost:4200/pay;id=1. This show Pay component with credit card fields generated by a external javascript (This javascript script is loaded from this component). But if i come from another component to this, Pay component doesn't show the credit card fields but load external script. How can I fix this?
My code
first.component.ts
let datos = {
id:'6'
}
this.router.navigate(['pay',datos]);
pay.component.ts
ngOnInit(): void {
this.loadScripts();
}
loadScripts() {
this.dynamicScriptLoader.load('2payjs').then(data => {
// Script Loaded Successfully
console.log('All elements loaded successfully')
this.loadElement();
}).catch(error => console.log(error));
}
loadElement(){
let that = this;
let id = this.router.snapshot.paramMap.get('id');
window.addEventListener('load', function() {
// Initialize the JS Payments SDK client.
let jsPaymentClient = new TwoPayClient('AVLRNG');
// Create the component that will hold the card fields.
let component = jsPaymentClient.components.create('card');
component.mount('#card-element');
// Handle form submission.
document.getElementById('payment-form').addEventListener('submit', (event) => {
event.preventDefault();
/// Extract the Name field value
const billingDetails = {
name: document.querySelector('#name').value
};
// Call the generate method using the component as the first parameter
// and the billing details as the second one
jsPaymentClient.tokens.generate(component, billingDetails).then((response) => {
//console.log(response.token);
let data = {
token:response.token
}
}).catch((error) => {
console.error(error);
});
});
});
}
const navigationExtras: NavigationExtras = {
queryParams: {
id: 1,
},
queryParamsHandling: 'merge'
};
this.router.navigate(['pay'], navigationExtras);
you need navigationExtras in order to create params in your router link and able to fetch by another component
Already solved. I just delete window load event listener.
I'm pretty new with React and I'm facing some trouble. I'm writing a Kibana plugin and I can't understand why my table does not update:
const getAllConfigurations = () => {
axios.get('../api/chimera-events-generator/configurations/get-all-configurations').then(res => {
console.log(res);
if (res.data.ok) {
setResponseTab(res.data.data);
setConfigurations(res.data.data);
}
});
}
const refresh = () => {
axios.get('../api/chimera-events-generator/get-all-info').then(res => {
if (res.data.ok) {
var tabTmp = responseTab;
tabTmp.push({
name: 'ajeje'
});
console.log(tabTmp);
setResponseTab(tabTmp);
}
}).catch(error => {
})
}
If I add a call to "getAllConfigurations" inside the refresh function, just before the rest call, it works fine. But without the "getAllConfigurations" call inside the refresh function, the table does not update at all. The row "ajeje" does not appear.
Any help would be appreciated.
I'm working with draft-js for react where I make an api call (IN A FUNCTIONAL PARENT COMPONENT) and get contents to be put up in the editor. I have this code to insert the fetched data into the editor after receiving it in props:
Parent Component:
var draftContent = "";
var isContentFetched = false;
const CommentSection = () => {
let response = await fetch(url, {
method: "get",
headers: headers,
});
let query = await response.json(); // read response body and parse as JSON
draftContent = element.comment;
isContentFetched = true;
return(<RichTextEditor
isDraftFetched={isDraftFetched}
isContentFetched={isContentFetched}
placeholder=""
rows={6}
boxWidth="100%"
boxHeight="155px"
/>)
})
Editor Component:
componentDidUpdate(props) {
if(this.props.isContentFetched == true && draftAlreadyFilled== false) {
this._insertText(this.props.draftContent);
draftAlreadyFilled = true;
}
}
_insertText(htmlContent) {
this.setState({
editorState: EditorState.createWithContent(
ContentState.createFromBlockArray(
convertFromHTML(htmlContent)
)
),
})
}
Problem is, the text loaded and sent through props does not fill up in the editor. Instead once I am in the page and I click on refresh, then it loads fine.
PS: 1. I have checked related questions and those solutions did not work. 2. It is really necessary that I make the API call in the parent component.
I'm new to Cypress. My app as a "routing system" manually changes window.location.hash.
At some point, I click on a button that changes the hash and consequently should change the page during the test. I can see a "new url" entry appearing during the execution, but how can I make cypress visit that url?
In few words, what the problem is: you can see I type the password and then {enter}. Running the test I can see the hash change in the address bar, but the page doesn't change in accord to the hash change.
This is the testing code
context("Workflow", () => {
it("login", () => {
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demo{enter}").should("have.value", "demo") // this should redirect to "/#home"
//cy.wait(10000)
cy.get(".subtitle").should("have.value", "Welcome") //this line fails as ".subtitle" is an element of "/#home"
})
})
EDIT: Following tons of failed attempts, I came up with a partially working, clunky and hacky solution. I think I shouldn't need to use reload() to solve that (there must be a better solution..), but to make it works I have to wait for all the remote requests to be done (otherwise reload() cancels them). I say partially working because you can see from the comments in the code if I try to visit #login first, then follow the redirect in #home and then change the page to #browser, the last one doesn't work (I can see the hash changing to #browser, but the page is still #home).
import 'cypress-wait-until';
let i = 0;
context("Workflow", () => {
it("login", () => {
cy.server( {
onRequest: () => {
i++;
},
onResponse: () => {
i--;
}
});
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demouser").should("have.value", "demouser")
cy.get("#password").type("demouser").should("have.value", "demouser")
cy.get("form#formLogin").submit()
cy.waitUntil(() => i > 0)
cy.waitUntil(() => i === 0)
cy.reload(); // it correctly change the hash AND the page to #home!
cy.url().should("include", "#home")
cy.get(".version").contains( "v2.0.0-beta") // it works!!
cy.get("a[data-id=browser]").click({force: true}) // it correctly changes the hash to #browser
cy.waitUntil(() => i > 0)
cy.waitUntil(() => i === 0)
cy.reload();
// the hash in the address bar is #browser, but the web page is #home
})
})
Cypress has an event called url:changed. See doc on Events here
Using this, something like this may work:
context("Workflow", () => {
it("login", () => {
cy.on('url:changed', url => {
cy.location('hash').then(hash => {
if (!url.endsWith(hash)) {
cy.visit(url);
}
});
});
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demo{enter}").should("have.value", "demo") // this should redirect to "/#home"
cy.get(".subtitle").should("have.value", "Welcome") //this line fails as ".subtitle" is an element of "/#home"
})
})
Edit: just for troubleshooting purposes and to focus on your issue, can you try it like this without cy.location():
context("Workflow", () => {
it("login", () => {
cy.on('url:changed', url => {
cy.visit(url);
});
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demo{enter}").should("have.value", "demo") // this should redirect to "/#home"
cy.get(".subtitle").should("have.value", "Welcome") //this line fails as ".subtitle" is an element of "/#home"
})
})
Edit: Have you tried cy.reload()
context("Workflow", () => {
it("login", () => {
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demo{enter}").should("have.value", "demo") // this should redirect to "/#home"
cy.reload();
cy.get(".subtitle").should("have.value", "Welcome");
})
})
Thanks for all the attempts to solve, but they were all tricky workarounds to something as simple as "trigger the related listener when window.location.hash changes".
The root of the problem was a bug in Cypress. The bug on window.location.hash is present in 4.5.0, but it has been solved somewhere between 4.5.0 and 4.12.1.
In 4.12.1 the problem is solved.
There are some ways to do that. One of the basic approach is like this:
cy.visit(`your_login_page`)
cy.get('[data-testid="input-username"]').type(`demo`, { force: true })
cy.get('[data-testid="input-password"]')
.type(`demo`, {
force: true,
})
.wait(1000)
.then(() => {
cy.location().should((loc) => {
expect(loc.pathname).to.eq(your_new_url)
})
})
You should add data-testid or findByTestId to your elements with a unique id.
To visit the new URL, you can use cy.visit(loc.pathname)