Rendered LocalStorage values being deleted after refresh page - javascript

I'm rendering some values of LocalStorage on the HTML page. But whenever I refresh the page, the rendered things get deleted even if the data is still stored in the localStorage. I would like the data to not be deleted on render. I have tried doing an if/else statement for this but have not had luck with it. Could anyone help me a way I could make this happen? Thank you!
This is my code:
let myLibrary = [];
const addBook = (event) => {
event.preventDefault()
var fields = {
title: document.getElementById("title").value,
author: document.getElementById("author").value,
pages: document.getElementById("pages").value,
checkbox: document.getElementById("checkbox").value
};
myLibrary.push(fields)
localStorage.setItem('books', JSON.stringify(myLibrary))
const data = JSON.parse(localStorage.getItem('books'))
if (localStorage.getItem('books')) {
document.getElementById('bookList').innerHTML = data.map(item => {
return `<div>
<div>Title: ${item.title}</div>
<div>Author: ${item.author}</div>
<div>Pages: ${item.pages}</div>
</div>`
console.log(data)
})
} else {
items = []
}
}

Related

Cypress V10. Not Reading data in BDD test: TypeError: Cannot read properties of undefined (reading 'mobileHandset')

I hope someone can help, I've just converted a Cypress Mocha framework to BDD. Before converting it was running perfectly and the test was running smoothly. Now I've converted it I seem to be getting an error message Cannot read properties of undefined (reading 'mobileHandset'). I never had this issue before so I'm very confused. here is the code and watch this video
Feature:
Feature: End to End Shopping Purchase Validation
Registered user will be able to purchase an item and have it shipped to their country
Scenario: Customer Purchase and delivery
Given I am on the eCommerce page
When I add items to cart
And I confirm shopping cart total
Then I select my delivery country and see a thank for your order notification
Step Definition
import { Given, And, Then, When } from "#badeball/cypress-cucumber-preprocessor";
import Homepage from '../../../support/pageObjects/Homepage'
import orderSummaryPage from '../../../support/pageObjects/orderSummaryPage'
import completeOrderPage from '../../../support/pageObjects/completeOrderPage'
const data = require ('../../../fixtures/example.json');
const homepage = new Homepage()
const StartCheckout = new orderSummaryPage()
const CompleteOrder = new completeOrderPage()
Given(/^I am on the eCommerce page$/, () => {
cy.visit(``+"/angularpractice/")
});
When(/^I add items to cart$/, function() {
homepage.getShopTab().click({force:true})
this.data.mobileHandset.forEach(function(element) {// this custom commad will add items to your cart
cy.AddToCart(element)
});
StartCheckout.getBasketCheckoutButton().click()
});
When(/^I confirm shopping cart total$/, () => {
let sum=0
CompleteOrder.getProductCost().each(($e1, index, $list) =>{
const unitCost=$e1.text()
let res= unitCost.split(" ")
res= res[1].trim()
sum=Number(sum)+Number(res)
}).then(function()
{
cy.log(sum)
})
});
Then(/^I select my delivery country and see a thank for your order notification$/, () => {
StartCheckout.getStartCheckoutButton().click()
CompleteOrder.getShippingCountry().type('United Kingdom')
CompleteOrder.getShippingCountryConfirm().click()
CompleteOrder.getTermsConditionsCheckbox().click({force: true})
CompleteOrder.getPurchaseButton().click()
CompleteOrder.getPurchaseAlert().then(function(element){
const actualText= element.text()
expect(actualText.includes('Success')).to.be.true
})
});
Here is the data
{
"name": "MY_NAME",
"gender": "Female",
"mobileHandset": ["Blackberry", "Nokia Edge"]
}
BeforeEach
beforeEach(function()
{
cy.fixture('example').then(function(data){
this.data=data
})
})
After discussion I moved the BeforeEach file to Support. Still getting the original error
You don't need to import the data fixture if you already have it in the cypress/fixtures folder.
You can load the fixture in the Before hook before your tests.
import {
Given,
And,
Then,
When,
Before
} from "#badeball/cypress-cucumber-preprocessor";
//...
Before(function() {
cy.fixture('example').then((data) => {
this.data = data;
});
});
//...
Your beforeEach() should be working, but it's not necessary you can just refer to data instead of this.data.
const data = require ('../../../fixtures/example.json'); // data available anywhere in this step
...
When(/^I add items to cart$/, () => {
...
data.mobileHandset.forEach(element => {
cy.AddToCart(element)
})
...
})
The convention is to use cy.fixture()
When(/^I add items to cart$/, () => {
...
cy.fixture('example.json').then(data => { // no ../.. needed
data.mobileHandset.forEach(element => {
cy.AddToCart(element)
})
})
...
});

React when useState change react-complex-tree not rerender

codesandbox link
I am using react-complex-tree to show my XML in tree format. I want to add button called ExpandAllTree
const [expandedItems,setExpandedItems] = useState([]);
I am holding my tree Items here
const traverseXml = (treeData, xmlObject) => {
treeData[xmlObject.name] = {
index: xmlObject.name,
canMove: false,
hasChildren: !!xmlObject.children.length,
children: xmlObject.children.map(c => c.name),
data: !xmlObject.children.length ? `${xmlObject.name}: ${xmlObject.value}` : xmlObject.name,
canRename: false
};
if (!xmlObject.children.isEmpty) {
xmlObject.children.forEach(c => {
setExpandedItems(oldArray => [...oldArray,xmlObject.name]);
traverseXml(treeData, c);
});
}
};
this code piece does travel all XML and create a data for react-complex-tree and also gets all Id's of tree element with
setExpandedItems(oldArray => [...oldArray,xmlObject.name]);
This part works perfect.
useEffect(() => {
setExpandedItems([]);
traverseXml(firstTreeData, DocumentXml);
traverseXml(secondTreeData, AppHdrXml);
}, [treeOpen]);
const handleOpenClick = () => {
setTreeOpen(!treeOpen);
}
whenever a button hits it should rerender. But It is not rendering. when I check the logs on first time page open
expandedItems is empty like an expected when I press the button expandedItems to get all tree IDs like expected again but in frontend nothings changes.
<UncontrolledTreeEnvironment
canDragAndDrop={true}
canDropOnItemWithChildren={true}
canReorderItems={true}
dataProvider={new StaticTreeDataProvider(secondTreeData, (item, data) => ({...item, data}))}
getItemTitle={item => item.data}
viewState={{
['Apphdr']: {
expandedItems:expandedItems
},
}}
>
<Tree treeId={"Apphdr"} rootItem={"AppHdr"}/>
</UncontrolledTreeEnvironment>
And there is no mistake on data type with expandedItems because when I give data manually which expandedItems gets, Tree shows as expanded.
When you changed to ControlledTreeEnviroment and set items like
items={firstTreeData}
Tree start to rerender

Framework7 + Vue + Firebase: Open an individual page displaying the dynamic info from the database?

How to I get to open a user with a dynamic url each to an individual page?
I use Framework7 + Vue for a Cordova Project.
I have customized the default product page that grabs an id and display data of a single product, It works by generating the unique ID (“uid” as per firebase) for each user in a url by it fails to pass it the user.vue page that I created, it doesn’t open when I click on it. What exactly could I be missing here? I don’t know much about JSON.stringify stuffs!
user.vue - the individual data page
<f7-page name="user">
<f7-navbar :title="user.username" back-link="Back"></f7-navbar>
<f7-block-title>About {{user.username}}</f7-block-title>
<f7-block strong>
{{user.email}}
</f7-block>
</f7-page>
<script>
export default {
data: function () {
var userId = this.$f7route.params.id;
var currentUser;
this.$f7.data.users.forEach(function (user) {
if (user.user_id === userId) {
currentUser = user;
}
});
return {
user: currentUser,
};
}
};
</script>
home.vue - the user list loop, working just fine as expected
<f7-list>
<f7-list-item
v-for="(user) in users"
:key="user.user_id"
:title="user.username"
:link="`/user/${user.user_id}/`"
></f7-list-item>
</f7-list>
home.vue - mounted functions script
mounted() {
let viewUsers = this;
const usersRef = firebase.database().ref("users");
usersRef.on("value", snapshot => {
let data = snapshot.val();
let users = [];
Object.keys(data).forEach(key => {
users.push({
id: key,
username: data[key].username,
user_email: data[key].email,
user_id: data[key].uid,
});
});
viewUsers.users = users;
});
}
home.vue - data returned script at the top
data() {
return {
users: this.$f7.data.users, //the arrays had already been called/initialized at the app.vue
}
routes.js:
import UserPage from ‘…/pages/user.vue’;
{
path: ‘/user/:id/’,
component: UserPage,
}
What exactly am i missing here?

ReactJS manipulating objects data extracted from SQLITE3 Database

I am working on a full stack application. I want to query my database for information and for it to show in a different input box. I successfully query my database and retrieve the information, but I can't put the actual information into the input area.
From the console.log I found out it is an object, and I looked for tutorials, but they still don't help me. I can convert it to a string and put it there, but it won't help me, as I need the specific column - for example, { "title": "Back to the Future" } - this is similar to mine, and I only want to extract "Back to the Future".
I tried with "Object.title", JSON.parse and then trying to access its properties, but still nothing. I get undefined at best. Here is the code in question.
MainFile.jsx
import React, {Component} from 'react';
import './Control1.css';
import axios from "axios";
class editShowing extends React.Component{
constructor(props){
super(props);
this.state={
showingId: '',
title: '',
showingsList: [],
}
this.handleSubmit = this.handleSubmit.bind(this);
this.onChangeTitle = this.onChangeTitle.bind(this);
this.onChangeShowingID = this.onChangeShowingID.bind(this);
}
onChangeShowingID(event){
this.setState({showingId: event.target.value});
}
onChangeTitle(event){
this.setState({title: event.target.value});
}
handleSubmit(event){
event.preventDefault();
axios.get('/api/getShowings',
{
params: {
showingId: this.state.showingId
}
})
.then(response => {
const { showingsList } = response.data
this.setState({ showingsList });
console.log(showingsList.title)
})
}
render(){
const { showingsList } = this.state
return(
<div>
<form onSubmit={this.handleSubmit}>
<h1> A new title to test GitFlow </h1>
<input onChange = {this.onChangeShowingID} type = "text" name = "showingId" placeholder = 'hi' value = {this.showingId}></input>
<input onChange = {this.onChangeTitle} value = {showingsList} type = "text" name = "title" placeholder = "title" />
<button type = "submit">Submit</button>
</form>
</div>
)
}
}
export default editShowing;
Server.js bit
app.get('/api/getShowings', (req,res) => {
console.log("I communicate with server.js")
datalayer.getShowings(req.query.showingId,
(err, result) => {
res.send(result);
})
});
DataLayer.js bit
module.exports.getShowings = (showingId, callback) => {
console.log("I connect to datalayer")
let sql = `SELECT title FROM showings WHERE id = ?;`
console.log("SQL CONNECTS")
db.get(sql, [showingId], (err, res) => {
if (err){
throw err;
}
console.log(res)
return callback(null, res)
})
}
To summarise, I want to put the data (only the actual title, not the whole object) of "ShowingsList" into the "title input", and I have a lot of options, but to no avail. I have been learning React.JS for the past 2 weeks.
I am extra lucky and found a solution 5 minutes after posting it. In the datalayer, instead of res you need to put row.title or the actual information you need from the database. My other mistake was that in the main jsx file I initiated ShowingsList as an object, so I changed it to a normal string, and it now works.

Can't get object key in firebase

Problem: I am making an app with Firebase and React Native where users can post, and then other users can comment on posts. To do the comments, I need to grab the key of the content of a post. I tried using the child.getKey() function, but that gave me an error.
child.getKey is not a function. (In 'child.getKey()', 'child.getKey' is undefined)
I would really love some help getting the key. Thank you!
Code
getItems(){
var items = [];
var query = ref.orderByKey();
query.once ('value', (snap) => {
snap.forEach ( (child) => {
items.push({
content: child.val().content,
key: child.getKey()
});
});
items.reverse();
}).then(() => {
this.setState({firebaseItems: items});
});
}
Firebase layout
Posts:
-Kier498dma39md:
content: 'This is an example post. The numbers above me are an example of the random key I am trying to get.'
So, I did some research, and eventually found out all I needed to do was use key: child.key

Categories