Categories
discuss

TypeError: Cannot read property ‘defaults’ of undefined when using the react wrapper of chartjs

I’m trying to use the react wrapper of chart.js and I’m having an issue. When I’m trying to add a chart, there is an error (” TypeError: Cannot read property ‘defaults’ of undefined”)

The code is the following:

import React, { useState, useEffect } from 'react';
import api from '../../services/API';
import './Graph.css';
import { Line } from 'react-chartjs-2';

export default function Graph() {
    const [dataChart, setDataChart] = useState({ });

    useEffect(() => {
        const abortController = new AbortController();
        const signal = abortController.signal;
        const getData = async() => {
            let confirmedCases = [];
            let dateOfCases = [];
            await api.get('btt-prices', {signal: signal})
            .then ( resp => {
                for (const dataObj of resp.data ) {
                    console.log( dataObj )
                    confirmedCases.push(dataObj.price);
                    let tempDate = new Date (dataObj.date);
                    dateOfCases.push(tempDate.getUTCDate());
                }
            });
            
            setDataChart({ 
                labels: dateOfCases, 
                datasets: [{ 
                  label: 'Confirmed cases', 
                  data: confirmedCases 
                }]
            });
    
            //console.log(dataChart)
        }

        getData();
        return () => {
            abortController.abort();
        }
    }, []);
    
    return(
        <div className='container'>
            <Line data={ dataChart }/>
        </div>   
    );
}

The error that shows is the following:

TypeError: Cannot read property 'defaults' of undefined
(anonymous function)
C:/Users/e/Desktop/test/front/node_modules/react-chartjs-2/es/index.js:643
  640 | }(_react["default"].Component);
  641 | 
  642 | exports.Scatter = Scatter;
> 643 | var defaults = _chart["default"].defaults;
  644 | exports.defaults = defaults;

I tried to search about it but I can’t see any solution… I tried to install again chartjs (besides react-chartjs) just in case, but the error still remains. How can I solve this error Thank you!

Answer

Which version of chart.js are you running because if you reinstalled it its a high chance you are running version 3 of the lib which is at the moment still not compatible with the wrapper so you will have to install the latest version 2 release of chart.js (2.9.4)

Categories
discuss

Native Admob ad causing window leak

I am displaying a native ad in an Activity which has FragmentContainerView to display different fragments. But when I exit the app using back button, I am getting the following error

E/WindowManager: android.view.WindowLeaked: Activity com.status.statusdownload.views.MainActivity has leaked window com.google.android.gms.internal.ads.zzbft{4119d98 I.E...... ......I. 0,0-840,0} that was originally added here
        at android.view.ViewRootImpl.<init>(ViewRootImpl.java:598)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:377)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:96)
        at com.google.android.gms.internal.ads.zzcen.zzh(com.google.android.gms:play-services-ads@@19.8.0:53)
        at com.google.android.gms.internal.ads.zzcdf.zzb(com.google.android.gms:play-services-ads@@19.8.0:134)
        at com.google.android.gms.internal.ads.zzcel.onGlobalLayout(com.google.android.gms:play-services-ads@@19.8.0:108)
        at com.google.android.gms.internal.ads.zzbbl.onGlobalLayout(com.google.android.gms:play-services-ads@@19.8.0:6)
        at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1056)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2629)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1722)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7621)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1029)
        at android.view.Choreographer.doCallbacks(Choreographer.java:852)
        at android.view.Choreographer.doFrame(Choreographer.java:787)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1014)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:235)
        at android.app.ActivityThread.main(ActivityThread.java:7441)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

I have destroyed reference to native ad using as per the official documentation (https://developers.google.com/admob/android/native/start)

if (isDestroyed) {
                    unifiedNativeAd.destroy()
                    return@forNativeAd
                }

Please help me solve this error.

Answer

It looks like the issue is caused by the new native validator, when I disable the validator in my manifest file the error goes away. Since the validator is automatically disabled for release builds. Disabling the validator using NATIVE_AD_DEBUGGER_ENABLED in the manifest file fixes both these issue.

Categories
discuss

What is the best way to have a fallback image in NextJS?

Recently, I have been working on a project in NextJS which uses the YoutubeAPI to fetch video information, including thumbnail URLs.

The thumbnail URL for a full resolution image looks like this: https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg

However, sometimes YouTube fails to generate a full-resolution image, and in that case, the image is not displayed on my webpage.

In the case that the image with the URL https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg does not exist I wish to use another URL like https://i.ytimg.com/vi/${videoId}/hqdefault.jpg

What is the best way to handle this with next/image?

Answer

These answers were helpful but there’s a way to achieve this without needing to pass a key each time by taking advantage of the useEffect hook:

useEffect(() => {
    set_imgSrc(src);
}, [src]);

Additionally, the onError event doesn’t seem to trigger for certain images (I believe layout='fill' doesn’t trigger it in certain scenarios), for those cases I’ve been using the onLoadingComplete and then I check if the width of the image is 0

onLoadingComplete={(result) => {
    if (result.naturalWidth === 0) {  // Broken image
        set_imgSrc(fallbackSrc);
    }
}}

Full code:

import Image from "next/image";
import { useEffect, useState } from "react";

export default function ImageFallback({ src, fallbackSrc, ...rest }) {
  const [imgSrc, set_imgSrc] = useState(src);

  useEffect(() => {
    set_imgSrc(src);
  }, [src]);

  return (
    <Image
      {...rest}
      src={imgSrc}
      onLoadingComplete={(result) => {
        if (result.naturalWidth === 0) {
          // Broken image
          set_imgSrc(fallbackSrc);
        }
      }}
      onError={() => {
        set_imgSrc(fallbackSrc);
      }}
    />
  );
}
Categories
discuss

Android 11 – Accessing Files in my app Android/Data folder

I’m really struggling with this for some reason and am hoping someone can help point me in the right direction.

I am targeting Android 11 / API 30 which is where the trouble seems to all stem from. Targeting lower might work for me – but it seems like Google is going to force me down this path eventually so I might as well just figure this out.

My apps typically write files out to the standard

getExternalFilesDir(null)

This gives me a path on the device which is

/storage/emulated/0/Android/data/com.domain.testapp/files

I also tried other types, like:

getExternalFilesDir(Environment.DIRECTORY_PICTURES)

results in

/storage/emulated/0/Android/data/com.domain.testapp/files/Documents

My app has no trouble actually writing files out to this location. In Android 11 I have to jump through some hoops with the local file explorer to see these files – but they do exist on the device.

I am now trying to give the user some ability to see the files and share the files and that’s where I’m stumped!

This code below results in no files found

File filePath = this.getExternalFilesDir(null);
String filePathString = filePath.toString();

ArrayList<String> myData = new ArrayList<>();
File fileDir = new File(filePathString);

String[] files = fileDir.list();

if(files.length == 0){
    Log.w(APPID, "NO FILES IN FOLDER");
}

Yes – I know the File and .toString() is not needed – but I was logging them out each step because I thought I was crazy.

I know for a FACT that there are a dozen or so files in the folder this is pointing to in this app. This app created the files. Shouldn’t it be able to see the files in the folder???

Manifest has the following permissions – which I dont think it needs all of:

<uses-permission android:name = "android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>

No permissions show as denied to the app

I thought about using the external storage – but it seems like this is even harder in Android 11? Or is that really an easier path to take?

I did try playing with this, but it seems deprecated and soon to be gone?

File downloadFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

which is this folder on my device

/storage/emulated/0/Download

And I can definitely see the files in there with any file explorer.

Any thoughts on how to get access to the files this app created?

I’m probably missing something really obvious.

Any suggestions welcomed!!

Answer

I Think I Have An Answer?

The more I read about this – it appears that Android 10 went one way, and then Android 11 back tracks it a little and re-enables some of the direct file path access.

Hopefully I’m right on this and won’t have to come back and re-do things again down the road

So the answer is to use the requestLegacyExternalStorage in the Manifest – even though it’s got all kinds of warnings

And then I created a folder in Documents with this

File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+File.separator+"MyAppFolder");
filePath.mkdirs();

And Now I can write to this and read from it.

Anyway – this seems to work for me on Android 9, 10 and 11. So hopefully the trend forward continues.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..