Client side React componentDidMount not called (without JSX) - html

I am learning React and following their step by step tutorial but without the use of JSX. I am not very far into the tutorial but I hit a snag. The componentDidMount method is not being called, and so my timer does not update.
Any help would be appreciated.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Test</title>
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<!--<script crossorigin src="assets/react.development.16.4.1.js"></script>-->
<!--<script crossorigin src="assets/react-dom.development.16.4.1.js"></script>-->
</head>
<body>
<div id="root"></div>
<script>
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "Hello World!",
date: new Date(),
}
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
render() {
let fragment = React.createElement(React.Fragment, null, [
React.createElement("h1", {key: "message"}, this.state.message),
React.createElement("p", {key: "time"}, this.state.date.toLocaleTimeString())
]);
return fragment;
}
tick() {
this.setState({
date: new Date()
});
}
}
ReactDOM.render(new App().render(), document.getElementById("root"));
</script>
</body>
</html>

I think the problem is there in one place
ReactDOM.render(new App().render(), document.getElementById("root"));
Why this will not work ?
Because render will return chilren of App component not the App itself
. Your children will be mounted first and your App is neverbe rendered
, hence no componentDidMount for App component
the context is not proper. Try using arrrow funciton here
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "Hello World!",
date: new Date(),
}
}
componentDidMount() {
console.log("mounting")
this.timerID = setInterval(
() => {
this.tick()
},
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
render() {
let fragment = React.createElement(React.Fragment, null, [
React.createElement("h1", {key: "message"}, this.state.message),
React.createElement("p", {key: "time"}, this.state.date.toLocaleTimeString())
]);
return fragment;
}
tick = () => {
debugger
this.setState({
date: new Date()
});
}
}
ReactDOM.render(React.createElement(App), document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<!--<script crossorigin src="assets/react.development.16.4.1.js"></script>-->
<!--<script crossorigin src="assets/react-dom.development.16.4.1.js"></script>-->
<div id="root"></div>

Related

window.MathJax is undefined?

Hi i Have a problem with MathJax library. I want to display the mathjax formula on the screen, but when I use window.MathJax I get the error that it is undefined. Here is how I installed the MathJax in my html file:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Test</title>
<link rel="icon" href="/icons/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/icons/favicon.ico" type="image/x-icon">
<!-- inject:css -->
<!-- endinject -->
<script type="text/x-mathjax-config">
MathJax = {
options: {
renderActions: {
addMenu: []
}
},
};
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
}
});
</script>
<script async type="text/javascript" src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-mml-svg.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
</head>
<body>
<div id="application-content">
</div>
</body>
<!-- inject:js -->
<!-- endinject -->
<script type="application/javascript">
EMBED.default.init();
</script>
</html>
And here is the component where I use the library:
import React, { Component } from 'react';
export default class MathBlock extends Component {
constructor(props) {
super(props);
this.state = {
open: false,
};
}
render() {
const text = this.props.block.getText();
const latexRegex = /\${2}(.*?)\${2}/;
const hasLatex = latexRegex.test(this.props.block.getText());
return (
<div>
<div
dangerouslySetInnerHTML={{
__html: hasLatex
? window.MathJax.tex2svg(text.replaceAll('$', '')).innerHTML
: window.MathJax.mathml2svg(text).innerHTML,
}}
/>
</div>
);
}
}
MathBlock.propTypes = {
block: React.PropTypes.object.isRequired,
};
Does anyone know what is the problem here?
Because the script tag that loads MathJax has the async attribute, it may not be loaded when your EMBED.default.init(); command likely will run before MathJax is loaded, and so before window.MathJax has been defined.
You could either remove the async attribute (which will mean your page will have to wait for MathJax to load and compile before the rest of the page is processed, slowing down your initial view of the page), or you could put the EMBED.default.init(); in MathJax's startup ready() function so that it is not performed until MathJax is loaded.
You are loading MathJax version 3, but your current configuration seems to be a mix of v2 and v3 configurations, and it is currently being ignored entirely by MathJax.
You could use
<script>
MathJax = {
options: {
renderActions: {
addMenu: []
}
},
tex: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
},
startup: {
ready() {
MathJax.startup.defaultReady();
EMBED.default.init();
}
}
};
</script>
(a correct v3 configuration) in place of your current configuration script, and see if that avoids the problem.

How to get data from json using axios in react?

There are two files reactjs.json in which..
{
"642176ece1e7445e99244cec26f4de1f":
["https://ih1.redbubble.net/image.487729686.1469/pp,550x550.jpg",
"https://ik.imagekit.io/PrintOctopus/s/files/1/0006/0158/7777/products/abey_pagal_hai_kya.png?v=1547744758"]
}
and index.html
<!DOCTYPE html>
<html>
<head>
<title>Image Viewer-Static</title>
<!-- <link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"
/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
/>
<link
rel="stylesheet prefetch"
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="style.css" /> -->
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/babel">
var imageslink;
class FetchDemo extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Pictures apikeys="642176ece1e7445e99244cec26f4de1f" />
</div>
);
}
}
class Pictures extends React.Component {
constructor(props) {
super(props);
axios.get('reactjs.json').then(
res => {
console.log(res.data);
imageslink = res.data;
console.log(imageslink);
})
}
render() {
return (
<div>
{imageslink[this.props.apikeys].map(function(name, index){
return <img key={index} src={name} />;
})}
</div>
);
}
}
ReactDOM.render(
<FetchDemo/>,
document.getElementById("root")
);
</script>
</body>
</html>
Error:
Actually I want to fetch data from the reactjs.json file into the index.html using ajax in react. I am using axios for this and for react I am using cdn. But I am unable to fetch the data .
I tried to put it in componentDidMount() in FetchDem class but not works so I PASSED IT INTO THE CONSTRUCTOR but still I am unable to access the data.
So my question is how to acess the data from reactjs.json file to index.html?
React documentation recommends using componentDidMount for API calls.
Also when you fetch the data, you have to keep it in the state. Later the data will be available in the render method.
Here's how you have to tune-up you code:
constructor(props) {
super(props);
this.state = { imageslink: null }
}
componentDidMount() {
axios.get('reactjs.json').then( res => {
this.setState({ imageslink: res.data })
})
}
render() {
const { imageslink } = this.state
if (imageslink) {
// Here you can access this.state.imageslink,
// because they will be fetched.
}
}
Here's a generic Axios React example:
class App extends React.Component {
constructor(props) {
super(props)
this.state = { users: [] }
}
componentDidMount() {
axios.get('https://reqres.in/api/users?page=1')
.then(response => this.setState({ users: response.data.data }))
}
renderUsers() {
const { users } = this.state
return users.map( user => (
<div key={user.id}>{user.first_name} {user.last_name}</div>
))
}
render() {
return <div>{ this.renderUsers() }</div>
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>

Ng-view or ui-view not displaying html page

I am relatively new to Angularjs, and am building a website. When I try to inject todo.html into the body tags of index.html nothing happens. I am not getting any errors in the console. I have read many of the similar posts to mine, and have already tried
Remove the ng-include from the body of index.html
Moved the links for angualrjs and bootstrap from the body of index.html to the head
Originally I used Ng-route but it did not work, so I implemented ui-router
I have tried both ng-route and ui-router,and both run without any errors. I don't think it has anything to do with either.
index.html
<html ng-app="todoApp">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->
<title>Todo App</title>
<!-- Angular ans JS links-->
<script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="app/app.js"></script>
<script src="app/services/todo.service.js"></script>
<script src="app/controllers/todo.controller.js"></script>
<!-- <script src="vendor/angular-route/angular-route.min.js"></script>-->
<!--Jquery and Bootstrap Links-->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://npmcdn.com/tether#1.2.4/dist/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/js/bootstrap.min.js" integrity="sha384-VjEeINv9OSwtWFLAtmc4JCtEJXXBub00gtSnszmspDLCtC0I4z4nqz7rEFbIZLLU"
crossorigin="anonymous"></script>
<!-- css links -->
<link href="vendor/bootstrap-css-only/css/bootstrap.min.css" rel="stylesheet"><!-- load bootstrap -->
<link rel="stylesheet" href="assets/css/todoApp.css">
<link rel="stylesheet" type="text/css" href="assets/css/Header-Picture.css">
</head>
<body >
<div ng-include="'app/views/header.html'"></div>
<!--<div ng-include="'app/views/footer.view.html'"></div>
-->
<ui-view></ui-view>
<!--<div ui-view></div>-->
</body>
</html>
App.js
var todoApp = angular.module('todoApp', [
'ui.router'
]);
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'views/todo.html',
controller: 'TodoController'
})});
todo.controller.js
todoApp.controller('TodoController', ['$scope', 'Todos', function TodoController($scope, Todos) {
$scope.formData = {};
console.log("in the TodoController");
// when landing on the page, get all todos and show them
Todos.get()
.success(function(data) {
$scope.todos = data;
});
// when submitting the add form, send the text to the spring API
$scope.createTodo = function() {
if(!$scope.todoForm.$valid) {
return;
}
Todos.create($scope.formData)
.success(function(data) {
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.todos.push(data);
});
};
// delete a todo after checking it
$scope.deleteTodo = function(id) {
Todos.delete(id)
.success(function(data) {
angular.forEach($scope.todos, function(todo, index){
if(todo.id == id) {
$scope.todos.splice(index, 1);
}
});
});
};
// when submitting the add form, send the text to the node API
$scope.saveTodo = function(todo) {
Todos.update(todo)
.success(function(data) {
$scope.editedTodo = {};
});
};
$scope.editedTodo = {};
$scope.editTodo = function(todo) {
$scope.editedTodo = todo;
}
$scope.revertTodo = function() {
$scope.editedTodo = {};
}
}]);
You should be using otherwise to force the first state to be loaded as below
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'todo.html',
})
$urlRouterProvider.otherwise('/');
});
Your index.html will look like
<div ng-include="'app/views/header.html'"></div>
<ui-view>
</ui-view>
LIVE DEMO
I added the code posted by #Aravind to my project which I belive was an improvement on my own and was correct. But the issue was the file path to the todo.html. The file path in the original was views/todo.html
the correct path is app/views/todo.html
My original code:
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'views/todo.html',
controller: 'TodoController'
})});
Current Working Code
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'app/views/todo.html',
})
$urlRouterProvider.otherwise('/');
});

ion-nav-view not working when trying to transition to new template

I am trying to figure out how to transition from one url to another using ion-nav-view. Visual Studio compiles the code and doesnt throw any errors when trying to load the templates/events.html in the tab. Any suggestions are welcome
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>SlidingTransitionwithAPI</title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"> </script>
<script src="cordova.js"></script>
<script src="lib/angular-ui-router/release/angular-ui-router.js"></script>
<script src="lib/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="lib/ionic-ion-swipe-cards/ionic.swipecards.js"></script>
<script src="lib/collide/collide.js"></script>
<script src="lib/ionic-ion-tinder-cards/ionic.tdcards.js"></script>
</head>
<body ng-app="starter" no-scroll>
<ion-nav-view>
</ion-nav-view>
</body>
app.js:
angular.module('starter', ['ionic', 'starter.controllers', 'ionic.contrib.ui.tinderCards', 'ui.router'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
.state('FindEvents', {
url: '/findEvents',
templateUrl: 'templates/events.html',
controller: 'EventsCtrl'
})
.state('favorites', {
url: '/favorites',
templateUrl: 'templates/favorites.html',
controller: 'FavoritesCtrl'
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/findEvents');
});
controllers.js:
angular.module('starter.controllers', [])
.directive('noScroll', function () {
return {
restrict: 'A',
link: function ($scope, $element, $attr) {
$element.on('touchmove', function (e) {
e.preventDefault();
});
}
}
})
.controller('EventsCtrl', function ($scope, $state) {
var cardTypes = [
{ image: './images/event1.jpeg', title: 'New Apple Release' },
{ image: './images/event2.jpeg', title: 'Digital Conference' },
{ image: './images/event3.jpg', title: 'Skyline Sessions' },
{ image: './images/event4.jpg', title: 'Secret Rooftop Party' },
{ image: './images/event5.jpeg', title: 'Smoking Lights' },
{ image: './images/event6.jpg', title: 'Antibes Color Run' },
{ image: './images/event7.jpg', title: 'Tomorrowland' },
{ image: './images/event8.jpeg', title: 'Steve Aoki Lighting Up Town' },
{ image: './images/event9.jpeg', title: 'Nice Yacht Party' },
{ image: './images/event10.jpg', title: 'Night Pool Party' },
];
$scope.cards = [];
$scope.addCard = function () {
for (var p = 0; p < 10; p++) {
var newCard = cardTypes[p];
newCard.id = Math.random();
$scope.cards.push(angular.extend({}, newCard));
}
}
$scope.addCard();
$scope.cardDestroyed = function (index) {
$scope.cards.splice(index, 1);
};
$scope.cardSwipedLeft = function (index) {
console.log('Left swipe');
}
$scope.cardSwipedRight = function (index) {
console.log('Right swipe');
}
$scope.cardDestroyed = function (index) {
$scope.cards.splice(index, 1);
console.log('Card removed');
}
//Transitioning between states
$scope.Favorites = function () {
$state.go('favorites');
}
});
events.html:
<ion-view view-title="Time 'N Joy '" ng-controller="EventsCtrl">
<ion-content ng-app="starter" >
<ion-pane>
<div class="bar bar-header bar-dark">
<button class="button button-clear button-icon icon ion-navicon"></button>
<div class="h1 title" font="6" color="white">Event Finder</div>
<button class="button button-clear" ng-click="Favorites()">
<i class="icon ion-heart"></i>
</button>
</div>
<td-cards>
<td-card id="td-card" ng-repeat="card in cards" on-destroy="cardDestroyed($index)"
on-swipe-left="cardSwipedLeft($index)" on-swipe- right="cardSwipedRight($index)"
on-partial-swipe="cardPartialSwipe(amt)">
<div class="title">
{{card.title}}
</div>
<div class="image">
<div class="no-text overlayBox"><div class="noBox boxed">Trash</div></div>
<img ng-src="{{card.image}}">
<div class="yes-text overlayBox"><div class="yesBox boxed" id="centerMe">Save</div></div>
</div>
</td-card>
</td-cards>
</ion-pane>
</ion-content>
</ion-view>
It is probably something very straigh forward but I have gone through countless examples and documents but cant find the error.

"Unknown Provider" AngularJS ngRoute

I'm working for the first time with Angular.js. I already search too many articles in order to correct this error. I receive the following error when my Index.html is loaded:
Here is the code:
report-module.js
angular.module('reportTemplateApp', [
'reportTemplateApp.services',
'reportTemplateApp.controllers',
'ngRoute'
]).
config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/slide1/:auditId', {
templateUrl: 'slide1.html',
controller: 'MainSlideController',
controllerAs: 'main'
})
.when('/slide3/:auditId/sl/:slideId', {
templateUrl: 'slide3.html',
controller: 'CommonSlidesController',
controllerAs: 'commons'
});
$locationProvider.html5Mode(true);
}]);
report-controller.js
angular.module('reportTemplateApp.controllers', []).
controller('CommonSlidesController', '$routeParams', function ($scope, $routeParams, auditAPIservice) {
$scope.id = $routeParams;
$scope.slideId;
$scope.slide = [];
//CANCEL EDIT
$scope.cancelSave = function () {
$scope.mainList = $scope.backupList;
}
//SAVE DATA
$scope.saveSlide = function () {
try {
auditAPIservice.ItemsData($scope.mainList).then(function (response) {
if (response.message = "Success") {
}
else {
$scope.mainList = $scope.backupList;
}
});
} catch (ex) {
$scope.showToast('UPS! Something happen ' + ex.message);
}
}
//GET DATA
reportAPIservice.getSlide(2, 3).then(function (response) {
if (response.message = "Success") {
$scope.mainList = response.data.ReportSlideInfo
angular.copy($scope.mainList, $scope.backupList);
}
else {
//SOME ERROR SHOWING HERE
}
});
$scope.showToast = function (message) {
angular.element(document).ready(function () {
toast(message, 4000);
});
}
}).
Index.html
<!DOCTYPE html>
<html>
<head>
<script src="../Scripts/jquery-1.7.1.js"></script>
<script src="../Scripts/materialize/materialize.min.js"></script>
<title></title>
<link rel="stylesheet" type="text/css" href="../Content/materialize/materialize.css" />
</head>
<body ng-app="reportTemplateApp">
<script>
$(document).ready(function () {
$(".button-collapse").sideNav();
$('.collapsible').collapsible();
});
</script>
Text Link<br/>
<div ng-view></div>
<script src="../Scripts/angular.js"></script>
<script src="../Scripts/angular-route.js"></script>
<script src="~/Scripts/angular-resource.js"></script>
<script src="../Scripts/SPS/Report/report-module.js"></script>
<script src="../Scripts/SPS/Report/report-controller.js"></script>
<script src="../Scripts/SPS/Report/report-service.js"></script>
</body>
</html>
I don't know what it's wrong. Another thing, the error shows when I add in the Index page, if I remove it no error is present.
I was able to fix this. I had (I don't know why) in the project mixed versions of the angular.js(1.2.23) and angular-route.js (1.3.8). After change one with the same version of the other there is no error and routing works.