Data version error in SPFX React -Basic Webpart - reactjs

I Just created a basic spfx webpart with react but getting bellow error:
{
"resource": "/c:/Node_Dev/CRUD_React/src/webparts/crudReact001/CrudReact001WebPart.ts",
"owner": "typescript",
"code": "2611",
"severity": 8,
"message": "'dataVersion' is defined as a property in class 'BaseClientSideWebPart', but is overridden here in 'CrudReact001WebPart' as an accessor.",
"source": "ts",
"startLineNumber": 35,
"startColumn": 17,
"endLineNumber": 35,
"endColumn": 28
}
My Code:
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '#microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '#microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '#microsoft/sp-webpart-base';
import * as strings from 'CrudReact001WebPartStrings';
import CrudReact001 from './components/CrudReact001';
import { ICrudReact001Props } from './components/ICrudReact001Props';
export interface ICrudReact001WebPartProps {
description: string;
}
export default class CrudReact001WebPart extends BaseClientSideWebPart<ICrudReact001WebPartProps> {
public render(): void {
const element: React.ReactElement<ICrudReact001Props> = React.createElement(
CrudReact001,
{
description: this.properties.description
}
);
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}

The article linked below provides more details on the issue:
https://dreamsof.dev/2020-09-21-typescript-upgrade-breaking-dataversion-get-override-spfx11/
The suggested solutions are:
Use Workspace Version for TypeScript (3.3.4000) instead of VS Code's newer version
Decorate method with // #ts-ignore

You can just delete 'datavaersion' method, it's compatible with SPFx v1.10 but will get an error when you install V1.11.

Related

Rendering data in React Native

I have an object named data that contains information about book. The simplest thing I want to do is render the book name. I am trying like below. Not working.
const data = {
"book": {
"id": "2d320",
"name": "book 1",
"Chapters": [
{
"No": "1",
"date": "2010-04-22",
"plots": [
{
"name": "Hero"
}
]
},
{
"No": "2",
"date": "2010-04-22",
"plots": [
{
"name": "Heroine"
}
]
},
]}}
export class Books {
render() {
return (
<View>
<div>{data.book.name}</div>
</View>
);
}
}
div should not be used in react-native, just replace it with Text after importing it. Secondly, class-based components should extend React.Component like so
import React, { Component } from 'react';
import { Text, View } from 'react-native';
const data = {
book: {
id: '2d320',
name: 'book 1',
Chapters: [
{
No: '1',
date: '2010-04-22',
plots: [
{
name: 'Hero',
},
],
},
{
No: '2',
date: '2010-04-22',
plots: [
{
name: 'Heroine',
},
],
},
],
},
};
class Book extends Component {
render() {
return <View>
<Text>{data.book.name}</Text>
</View>;
}
}
export default Book;
Here is a snack displaying the output you want.
If you don't want to import Component from 'react' and like to export directly then may also use this syntax
export default class Book extends React.Component {
render() {
return (
<View>
<Text>{data.book.name}</Text>
</View>
);
}
}

How to convert API Object to Array

I stuck with this error ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
I am trying to fetch data from API but it's showing me this error, as I am still learning angular please guide me on how to tackle this kind of errors.
metadata-service.service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { Pincodes } from 'src/app/Model/Pincodes';
import { baseURL } from 'src/environments/environment';
#Injectable({
providedIn: 'root'
})
export class MetadataServiceService {
constructor(private http:HttpClient) { }
public GetPincodes() : Observable<any> {
console.log("Calling GetPincodes API")
return this.http.get("/Metadata/api/metadata/getpincodes") // My API Link
}
}
API consist of the following data
{
"program": null,
"version": null,
"dateTime": null,
"success": true,
"errorCode": null,
"errorMessage": null,
"message": "Pincodes read Successfully",
"data": [
{
"pincode": 400708,
"village": "Airoli",
"taluka": "Thane",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 416007,
"village": "Kaamba",
"taluka": "Kalyan",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 421102,
"village": "Atali",
"taluka": "Kalyan",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 421501,
"village": "Ambarnath",
"taluka": "Ambarnath",
"district": "Thane",
"state": "Maharashtra"
},
{
"pincode": 421503,
"village": "Ambeshiv",
"taluka": "Ambarnath",
"district": "Thane",
"state": "Maharashtra"
}
]
}
I am interested in the data array
Pincode.ts
export class Pincodes {
pincode : number
village : string
taluka : string
district : string
state : string
}
register-page.component.ts
import { Component, OnInit } from '#angular/core';
import { data } from 'jquery';
import { Pincodes } from 'src/app/Model/Pincodes';
import { MetadataServiceService } from 'src/app/shared/services/metadata-service.service';
import { Albums } from "src/app/Model/albums";
import { Observable, of } from 'rxjs';
import {MatTableDataSource, MatTableModule} from '#angular/material/table';
import { report } from 'process';
#Component({
selector: 'app-register-page',
templateUrl: './register-page.component.html',
styleUrls: ['./register-page.component.css']
})
export class RegisterPageComponent implements OnInit {
observeData : Pincodes[]
modifiedText: any;
PinSelected : any = {}
constructor(private _metadataService: MetadataServiceService) { }
ngOnInit(){
this._metadataService.GetPincodes()
.subscribe(data => {
this.observeData = data;
});
}
onPincodeSelected(val : Pincodes){
console.log("value" + val);
this.customFunction(val)
}
customFunction(val : Pincodes){
this.modifiedText = "The Selected Pin was " + val.pincode + " and selected District is " + val.village
console.log("modifiedText" + this.modifiedText);
console.log("Pincode Selected" + this.PinSelected);
console.log("observeData Selected" + this.observeData);
}
}
register-page.component.html
<select
[(ngModel)]="PinSelected"
(ngModelChange)="onPincodeSelected($event)"
>
<option *ngFor="let pin of observeData" [ngValue]="pin">
{{ pin.pincode }}
</option>
</select>
<div>
<p>{{ modifiedText }}</p>
</div>
Error: Cannot find a differ supporting object '[object Object]' of type 'object'.
Try this:
ngOnInit(){
this._metadataService.GetPincodes()
.subscribe(res=> {
this.observeData = res.data;
});
}

Invariant Violation: View config getter callback for component `Home` must be a function (received `undefined`)

I want to call the function using the key name from the array on the tab.screen component.
my code is like this:
import React from 'react';
import { Text, View, TouchableOpacity, Modal } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import Icon from 'react-native-vector-icons/FontAwesome5';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import Home from '../mainscreen/GeneralScreen';
import Core from '../mainscreen/CoreScreen';
import Docs from '../mainscreen/GeneralScreen';
import ESS from '../mainscreen/GeneralScreen';
import General from '../mainscreen/GeneralScreen';
import HR from '../mainscreen/GeneralScreen';
import Payroll from '../mainscreen/GeneralScreen';
import Server from '../mainscreen/CoreScreen';
const Tab = createBottomTabNavigator();
const tabcomponents = {
"Home" : Home,
"Core" : Core,
"Docs" : Docs,
"ESS" : ESS,
"General" : General,
"HR" : HR,
"Payroll" : Payroll,
"Server" : Server
};
class TabNavigator extends React.Component {
constructor() {
super();
this.state = {
dashboardtab:[],
}
this.tabnavigatorasync();
}
tabnavigatorasync = async () => {
try {
const dashboardtab = await AsyncStorage.getItem('dashboardtab');
const dashboardtabParse = JSON.parse(dashboardtab);
this.setState({dashboardtab: dashboardtabParse});
//console.log('isi dari tab navigator: ', this.state.dashboardtab);
//console.log('------------------------------------------------');
//console.log('isi dari tab navigator 2: ', this.state.dashboardtab2[0].label);
} catch (error) {
}
}
render(){
//console.log('dashboardtab', this.state.dashboardtab);
const tabnavigatorRender = this.state.dashboardtab.map((item, index) =>
const tabcomponentsrender = tabcomponents[item.admintab.label];
return <Tab.Screen name={item.admintab.label} component={tabcomponentsrender} key={index}/>
);
return(
<Tab.Navigator>
{tabnavigatorRender}
</Tab.Navigator>
)
}
}
export default TabNavigator;
the result appears an error like this:
Invariant Violation: View config getter callback for component Home must be a function (received undefined)
This is the contents of the array:
[
{
"tab_id": "home",
"order": 10,
"admintab": {
"label": "Home",
}
},
{
"tab_id": "core",
"order": 1,
"admintab": {
"label": "Core",
}
},
{
"tab_id": "docs",
"order": 2,
"admintab": {
"label": "Docs",
}
},
{
"tab_id": "ess",
"order": 50,
"admintab": {
"label": "ESS",
}
},
{
"tab_id": "general",
"order": 45,
"admintab": {
"label": "General",
}
},
{
"tab_id": "hr",
"order": 40,
"admintab": {
"label": "HR",
}
},
{
"tab_id": "payroll",
"order": 42,
"admintab": {
"label": "Payroll",
}
},
{
"tab_id": "server",
"order": 70,
"admintab": {
"label": "Server",
}
}
]
is there something wrong with the code i made?
In your case, you want to use Dynamic Component Names.
First of all import your tabs.
import Home from 'path_to_your_tab_component/Home';
import Core from 'path_to_your_tab_component/Core'; // and so on
Then pass them in the object and give them a key based on their names.
const components = {
"Home": Home
"Core": Core // and so on
}
Inside the map, create a component from this object.
const tabnavigator = this.state.dashboardtab.map((item, index) => {
const TabComponent = components[item.admintab.label];
return <Tab.Screen name={item.admintab.label} component={TabComponent} key={index}/>
});

Accessing Cookies API from a React WebExtension

Summary
I'm trying to access the Cookies API from a WebExtension which uses React, but I don't know why, it throws a TypeException, as if browser.cookies did not exist.
I've checked permissions and the code is copy/pasted from the MDN docs... but still I can't get it to work.
Exception:
TypeError: browser.cookies is undefined
Code
This is the main component:
import React from 'react';
import ReactDOM from 'react-dom';
class Popup extends React.Component {
constructor(props) {
super(props);
this.state = { sessionId: null };
}
componentDidMount() {
var getting = browser.cookies.getAllCookieStores(); // This throws "TypeError: browser.cookies is undefined"
getting.then(logStores);
}
render() {
return (
<div>
<h1>My App</h1>
</div>
);
}
logStores(cookieStores) {
for (let store of cookieStores) {
console.log(`Cookie store: ${store.id}\n Tab IDs: ${store.tabIds}`);
}
}
}
ReactDOM.render(<Popup />, document.getElementById('app'));
And this is the manifest.json with the according permissions:
{
"manifest_version": 2,
"name": "MyApp",
"version": "1.0",
"browser_action": {
"browser_style": true,
"default_icon": {
"48": "images/Watermelon-48.png",
"96": "images/Watermelon-96.png"
},
"default_title": "MyApp",
"default_popup": "popup.html"
},
"permissions": ["browser", "cookies","<all_urls>","tabs"]
}
could you replace
"permissions": ["browser", "cookies","<all_urls>","tabs"]
By
"permissions": ["browserSettings", "cookies","<all_urls>","tabs"]

Can't show data from local json file in browser

I want to show JSON data in browser so that model, provider, storage and condition displays in separate divs.
There is no error in console and i can't figure out where is the problem.
Link updated for stackblitz, kindly have a look into it.
Github Repo
Here is the link for stackblitz.
iphone.json
{
"model": [
"iPhone 5",
"iPhone 5s",
"iPhone SE"
],
"provider": [
"Unlocked",
"AT&T"
],
"storage": [
"16",
"32"
],
"condition": [
"Brand New",
"Mint"
]
}
sell.service.ts
import { Injectable } from '#angular/core';
import { Observable } from "rxjs/Observable";
import { Http, Response } from "#angular/http";
import { HttpClient} from '#angular/common/http';
import "rxjs/add/operator/map";
export interface Staticdata {
model: Array<Model>;
provider: Array<Provider>;
storage: Array<Storage>;
condition: Array<Condition>;
}
export interface Model {
name: string;
}
export interface Provider {
carrier: string;
}
export interface Storage {
size: number;
}
export interface Condition {
quality: string;
}
#Injectable()
export class SellService {
fileUrl = '../static-data/iphone.json';
constructor(public http:HttpClient) {}
getData(){
return this.http.get(this.fileUrl);
}
}
sell-iphone.component.ts
import { Component, OnInit } from '#angular/core';
import { SellService, Staticdata } from "../shared/sell.service";
import * as data from "../static-data/iphone.json";
#Component({
selector: 'app-sell-iphone',
templateUrl: './sell-iphone.component.html',
styleUrls: ['./sell-iphone.component.css'],
providers: [ SellService ]
})
export class SellIphoneComponent implements OnInit {
constructor(public sellService: SellService){
}
ngOnInit() {}
staticData : Staticdata;
showData(){
return this.sellService.getData().subscribe((data: Staticdata) => this.staticData = {
model: data.model,
provider: data.provider,
storage: data.storage,
condition: data.condition
});
}
}
your json must be like:
{
"model": [
{
"name": "iPhone 5"
},
{
"name": "iPhone 5s"
},
{
"name": "iPhone SE"
}
],
"provider": [
{
"carrier": "Unlocked"
},
{
"carrier": "AT&T"
}
],
"storage": [
{
"size": "16"
},
{
"size": "32"
}
],
"condition": [
{
"quality": "Brand New"
},
{
"quality": "Mint"
}
]
}
Or you must transform the data you received. You can do it in the service better than in the component.
getData(){
return this.http.get(this.fileUrl).pipe(map((res:any)=>{
return {
model:res.model.map(m=>{return {name:m}}),
provider:res.provider.map(p=>{return{carrier:p}}),
storage:res.storage.map(s=>{return{size:s}}),
condition:res.condition.map(c=>{return{quality:c}})
}
})
);
}
If you're using angular-cli, you must put your file.json in the folder "assets"

Resources