How do I get the innerHTML while ignoring child elements? [duplicate]

I have an HTML div element with an innerHTML of x number. Through javascript, I add children to the element with their own innerHTML and append it to the existing div. But I can no longer call innerHTML to get the x in an easy way. This is probably a popular question but I haven’t found a solution that actually works. Is there any elegant way to do this with vanilla js or jquery? If there are any workaround like creating a variable that would be fine with me, but innerHTML I think is a good way to have both a variable and a visual representation.

Add aria-label to table header in datatable

let checkboxColumn = `<div class="checkbox c-checkbox" >
                          <label> <input type="checkbox"
                              ng-model="self.headerCheckBox" ng-change="self.headerSelected()"
                               /> <span
                              class="fa fa-check"></span>
                          </label>
                        </div>`;

   self.dtColumns = [
      DTColumnBuilder.newColumn("select").withTitle(checkboxColumn).notSortable(),
      DTColumnBuilder.newColumn("type").withTitle("Type").notSortable().withClass('min-width-100'),
      DTColumnBuilder.newColumn("ip").withTitle("Value").notSortable().withClass('min-width-250'),
      ]

I am creating a data table in which there is a checkbox in the header, clicking on it will select all the checkboxes of the row. The issue is that checkboxcolumn is getting rendered in aria-label as well. The snippet below will tell you what is getting rendered:

<th class="sorting_disabled" rowspan="1" colspan="1" style="width: 0px;" aria-label="
   <input type=&quot;checkbox&quot;
   ng-model=&quot;self.headerCheckBox&quot; ng-change=&quot;self.headerSelected()&quot;
   /> <span
   class=&quot;fa fa-check&quot;>
   ">
   <div class="checkbox c-checkbox">
      <label> <input type="checkbox" ng-model="self.headerCheckBox" ng-change="self.headerSelected()"> <span class="fa fa-check"></span>
      </label>
   </div>
</th>

You can see the content of the header and aria-label value are the same. How can I assign a different value to the aria-label? Help will be appreciated.

Angular: Testing apis from component

I have started learning how to test angular projects. So far basic unit testing is working fine for me but for the dependency testing especially when API services are injected into the component I am facing issue for providing HttpClient. I have tried different solutions but none is working for me.

Service

// Present in HttpClientService file
getDisposition() {
  return this.http.get<{ message: string, data: { dispositionList: Disposition[] } }>(`${this.URL}/disposition/get`);
}

// Present in FileProcessService file
deleteMedia(media: string) {
    return this.http.delete<{ message: string }>(`${this.URL}/certificate/delete?certificate=${media}`);
}

add-edit-activity.component.ts

import { HttpEventType } from '@angular/common/http';
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { AssignedPerson } from '@model/assigned-person.model';
import { Disposition } from '@model/disposition.model';
import { mimeTypes } from '@model/mime-type';
import { FileProcessService } from '@service/file-process.service';
import { HttpClientService } from '@service/http-client.service';
import { DeleteComponent } from '@shared/delete/delete.component';
import { CustomErrorStateMatcher } from '@validator/error-state-matcher';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-add-edit-activity',
  templateUrl: './add-edit-activity.component.html',
  styleUrls: ['./add-edit-activity.component.css']
})
export class AddEditActivityComponent implements OnInit {

  constructor(private fb: FormBuilder, private sanitizer: DomSanitizer, private dialogRef: MatDialogRef<AddEditActivityComponent>, @Inject(MAT_DIALOG_DATA) public data: any,
    private _http: HttpClientService, private _fileService: FileProcessService, private toastr: ToastrService, private dialog: MatDialog,) { }

  re = new RegExp(/^[a-zA-Z-]*/, 'g');
  ISOstamp = { T: ' ', Z: '000' };
  matcher = new CustomErrorStateMatcher();
  dispositionList: Disposition[] = [];
  assignedPersonList: AssignedPerson[] = [];
  filterAssignedPersonList: AssignedPerson[] = [];
  uploaded = false;
  uploadProgress = false;
  fileURL: SafeUrl;
  activityForm = this.fb.group({
    gaugeId: [this.data.gaugeId, Validators.maxLength(9)], createTimeStamp: [{ value: new Date().toISOString().replace(/[TZ]/g, m => this.ISOstamp[m]), disabled: true }],
    user: [{ value: sessionStorage.getItem('username'), disabled: true }], disposition: ['', [Validators.required, Validators.maxLength(30)]],
    assignedPersonName: ['', Validators.maxLength(30)], department: ['', Validators.maxLength(20)],
    shift: ['', Validators.maxLength(1)], remark: ['', Validators.maxLength(50)],
    calibrationDate: ['', Validators.maxLength(10)], attachment: ['', Validators.maxLength(255)]
  });

  @ViewChild('file') certificate: ElementRef;

  ngOnInit(): void {
    this.data.type.match(this.re)[0] === 'Update' && this.setFormValues();
    this._http.getDisposition().subscribe(response => this.dispositionList = response.data.dispositionList);
    this._http.getAssignedPerson().subscribe(response => this.assignedPersonList = this.filterAssignedPersonList = response.data.assignedToList);
  }

  get GaugeId() {
    return this.activityForm.get('gaugeId');
  }

  get TimeStamp() {
    return this.activityForm.get('createTimeStamp');
  }

  get Attachment() {
    return this.activityForm.get('attachment');
  }

  get Disposition() {
    return this.activityForm.get('disposition');
  }

  get DispositionValue() {
    return this.dispositionList.map(e => e.dispositionType).indexOf(this.Disposition.value) < 0;
  }

  get AssignedTo() {
    return this.activityForm.get('assignedPersonName');
  }

  get AssignedToValue() {
    return this.assignedPersonList.map(e => `${e.firstName} ${e.lastName}`).indexOf(this.Disposition.value) < 0;
  }

  private async setFormValues() {
    this.activityForm.patchValue({ ...this.data });
    if (this.data.attachment) {
      this.uploadProgress = true;
      this.uploaded = true;
      await this.fetchUploadedFile(this.data.attachment, mimeTypes[this.data.attachment.split('.')[1]]);
      this.activityForm.markAsPristine();
    }
  }

  searchAssignedPerson(event) {
    if (event.target.value) {
      this.filterAssignedPersonList = [];
      for (let person of this.assignedPersonList) {
        if (person.firstName.toLowerCase().startsWith(event.target.value.toLowerCase())) {
          this.filterAssignedPersonList.push(person);
        }
      }
    } else { this.filterAssignedPersonList = this.assignedPersonList }
  }

  upload(event) {
    const file: File = event.target.files[0];
    this.certificate.nativeElement.value = '';
    if (file.size > (20 * 1000 * 1000)) { // Checking if File size is above 20MB
      this.toastr.error('Size of ' + file.name + ' is above 20MB');
      return;
    }
    const fd = new FormData();
    fd.append('certificate', file, file.name);
    this.processAttachment(fd);
  }

  private processAttachment(file: FormData) {
    this._fileService.uploadMedia(file).subscribe(event => {
      if (event.type === HttpEventType.UploadProgress) { this.uploadProgress = true }
      if (event.type === HttpEventType.Response) {
        let media = event.body.data.Certificate;
        this.fetchUploadedFile(media.fileName, media.fileType);
        this.toastr.info(event.body.message);
      }
    }, error => {
      this.toastr.error(error.error.message);
      this.uploadProgress = false;
    });
  }

  private async fetchUploadedFile(file: string, mimeType: string) {
    try {
      let response = await this._fileService.getMedia(file).toPromise();
      this.fileURL = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(new Blob([response], { type: mimeType })));
      this.uploaded = true;
      this.uploadProgress = false;
      this.activityForm.patchValue({ attachment: file });
      this.Attachment.markAsDirty();
    } catch (error) {
      this.uploadProgress = false;
      this._fileService.processError(error.error)
    }
  }

  deleteFile() {
    this.dialog.open(DeleteComponent, {
      width: '350px', disableClose: true
    }).afterClosed().subscribe(response => {
      if (response) {
        this._fileService.deleteMedia(this.Attachment.value).subscribe(response => {
          this.toastr.info(response.message);
          this.activityForm.patchValue({ attachment: '' });
          this.Attachment.markAsDirty();
          this.uploaded = false;
        }, error => this.toastr.error(error.error.message));
      }
    });
  }

  async doAction() {
    let message = '';
    if (this.data.type.match(this.re)[0] === 'Add') {
      message = await (await this._http.addActivityLog(this.activityForm.getRawValue()).toPromise()).message;
    } else {
      message = await (await this._http.updateActivityLog(this.GaugeId.value, this.TimeStamp.value, this.activityForm.getRawValue()).toPromise()).message;
    }
    this.dialogRef.close(message);
  }
}

add-edit-activity.component.spec.ts

import { ComponentFixture, TestBed, tick } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FileProcessService } from '@service/file-process.service';
import { HttpClientService } from '@service/http-client.service';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { AddEditActivityComponent } from './add-edit-activity.component';

describe('AddEditActivityComponent', () => {
  let component: AddEditActivityComponent;
  let fixture: ComponentFixture<AddEditActivityComponent>;
  let _http: HttpClientService, _file: FileProcessService;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [AddEditActivityComponent],
      imports: [FormsModule, ReactiveFormsModule],
      providers: [
        { provide: MatDialogRef, useValue: {} },
        { provide: MAT_DIALOG_DATA, useValue: { type: 'Add Activity Log', gaugeId: 'W-001' } },,
        { provider: HttpClientService, useValue: null },
        { provider: FileProcessService, useValue: null }
      ]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AddEditActivityComponent);
    component = fixture.debugElement.componentInstance;
    _http = fixture.debugElement.injector.get(HttpClientService);
    _file = fixture.debugElement.injector.get(FileProcessService);
    fixture.detectChanges();
  });
  
  // These 2 tests throwing error.
  it('SHOULD mock http service', () => {
    let spy = spyOn(_http, 'getDisposition').and.callFake(() => {
      return of({
        message: '',
        data: { dispositionList: [] }
      }).pipe(delay(100));
    });
    component.ngOnInit();
    tick(100);
    expect(component.dispositionList).toEqual([]);
  });

  it('SHOULD mock file service', () => {
    let spy = spyOn(_file, 'deleteMedia').and.callFake((file: string) => {
      return of({ message: '' }).pipe(delay(100));
    });
    component.deleteFile();
    tick(100);
    expect(component.uploaded).toBe(false);
  });
});

The error that am getting for those 2 tests (I’m providing the error of 1 test case, the same is coming for the 2nd one also):

  1. SHOULD mock http service
    AddEditActivityComponent
    Error: Invalid provider for the NgModule ‘DynamicTestModule’ – only instances of Provider and Type are allowed, got: […, …, …,
    …, ?undefined?, …, …]
    at throwInvalidProviderError (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:240:1)
    at providerToFactory (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11550:1)
    at providerToRecord (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11521:1)
    at R3Injector.processProvider (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11424:1)
    Error: : could not find an object to spy upon for getDisposition() Usage: spyOn(, ) Error: :
    could not find an object to spy upon for getDisposition() Usage:
    spyOn(, )
    at

Anyone, please help what’s the exact error happening with my test cases? Stuck here for almost 2 days.

Making an inactive browser tab active again automatically using react js

Im building a react app. in the app, Im receiving a message through an API and if I receive a message, the message automatically display to the user.

But the problem is if the user is on another tab, they cannot see whether a message is received. I want to make the react app tab active immediately if the user is browsing on another tab after receiving a message. Is there a way in react to make the tab automatically active?

Out of memory issue with Chrome and unit tests

I have a test suite of around 800 tests in a repository.
When I run the tests locally I end up with an Aw Snap screen at some point during the tests running.
It’s more or less running on the build server (running headless), but locally it breaks almost every time.

Is there any way to free up memory to make it possible to run through the tests locally again?
It’s an issue that recently started to appear and we haven’t changed the unit tests to something that should cause this issue so I am afraid that it has to do with a Chrome update or so.

We have an index file that runs
WCT.loadSuites([arrayOfSuites]) and each unit test have their own file
with suite(), setup and tests.

Thanks

React – Function calling API uses default state parameters instead of correct state parameters

I am having trouble with the below code. This is a basic table which displays users and I am trying to implement some sort functionality however it is not working.

When running I can click the sort buttons and they will update the sortParameters state accordingly, however, the function which requests the data from the API (getUsersFromAPI) does not recognise this state change. When running this function is supposed to fetch the data and then use the reducer to sort according to the updated sortParameters, but it instead is returning the usersList as it is received from the API and the console.log(sortParameters) returns the defaultSortParameters. I am not sure why sortParameters isn’t updating in this function when a sort button is clicked?

Any help would be greatly appreciated.

Thanks,

Greg

    useState,
    useReducer,
    useEffect,
    useLayoutEffect,
    useContext,
} from "react";
import { useUser } from "../../contexts/UserContext";
import { usersListReducer } from "../../reducers/usersListReducer";
import {
    API_users_usersGetAllUsers,
    API_users_DeleteUser,
} from "../../publicFunctions/usersAPI";

// reactstrap components
import {
    Card,
    CardHeader,
    CardBody,
    CardTitle,
    Table,
    Row,
    Col,
    ButtonGroup,
    Button,
} from "reactstrap";

import NewUser from "../Users/NewUser";
import classNames from "classnames";

const defaultSortParameters = { sortType: "NAME", sortDirection: true };

const Users = () => {
    //------------------------- STATE -------------------------
    const currentUser = useUser();
    const [showNewUser, setShowNewUser] = useState(false);
    const [sortParameters, setSortParameters] = useState(defaultSortParameters);
    const [usersList, usersDispatch] = useReducer(usersListReducer, []);

    //-------------------- CLICK HANDLING ---------------------
    const deleteUser = async (id, name) => {
        //check if trying to delete self
        if (currentUser.id === id) return alert("Cannot delete self");

        //check for delete confirmation
        if (
            window.confirm("Are you sure you want to delete user " + name) === true
        ) {
            //remove user from userList if OK status is returned
            const result = await API_users_DeleteUser(id);
            if (result.statusText === "OK") {
                usersDispatch({
                    type: "DELETE_USER_BY_ID",
                    payload: id,
                });
            }
        }
    };

    //sorting by column
    const sortUsers = (sortType) => {
        setSortParameters({
            ...sortParameters,
            sortType: sortType,
            sortDirection: !sortParameters.sortDirection,
        });
        usersDispatch({
            type: "SORT",
            payload: {
                sortType: sortType,
                sortDirection: sortParameters.sortDirection,
            },
        });

        console.log(sortParameters);
    };

    //----------------------- MOUNTING ------------------------
    //get users from API when component mounts
    useEffect(() => {
        //get initial data on mount
        getUsersFromAPI();
        //set interval to refresh data periodically
        const interval = setInterval(() => {
            getUsersFromAPI();
        }, 5000);
        return () => {
            clearInterval(interval);
        };
    }, []);

    //----------------------- UPDATING ------------------------
    const newUser = () => {
        setShowNewUser(!showNewUser);
    };

    //----------------------- FUNCTIONS -----------------------
    const getUsersFromAPI = async () => {
        let result = await API_users_usersGetAllUsers();
        if (result === undefined) {
            console.log("ERROR: Cannot get users in Users.js");
        } else {
            usersDispatch({
                type: "GET_USERS_FROM_API",
                payload: result,
            });
            usersDispatch({
                type: "SORT",
                payload: {
                    sortType: sortParameters.sortType,
                    sortDirection: sortParameters.sortDirection,
                },
            });
        }
        console.log(sortParameters);
    };

    //------------------------ RENDER -------------------------
    return (
        <>
            <div className="content">
                <button onClick={() => console.log(currentUser)}>user</button>
                <button onClick={() => console.log(sortParameters)}>sort params</button>
                <Row>
                    <Col md="12">
                        <Card>
                            <Col sm="6">
                                <ButtonGroup
                                    className="btn-group-toggle float-left"
                                    data-toggle="buttons"
                                >
                                    <Button
                                        className={classNames("btn-simple", {
                                            active: showNewUser === true,
                                        })}
                                        color="info"
                                        id="0"
                                        size="sm"
                                        onClick={newUser}
                                    >
                                        New user
                                    </Button>
                                </ButtonGroup>
                            </Col>

                            <Col>
                                {showNewUser ? (
                                    <NewUser
                                        setShowNewUser={setShowNewUser}
                                        getUsersFromAPI={getUsersFromAPI}
                                    />
                                ) : (
                                    <></>
                                )}
                                <h2>Need a search Bar</h2>
                            </Col>

                            <CardHeader>
                                <CardTitle tag="h4">Users</CardTitle>
                            </CardHeader>

                            <CardBody>
                                <Table className="tablesorter" responsive>
                                    <thead className="text-primary">
                                        <tr>
                                            <th>
                                                Name{" "}
                                                <button onClick={() => sortUsers("NAME")}>sort</button>
                                            </th>
                                            <th>
                                                Email
                                                <button onClick={() => sortUsers("EMAIL")}>sort</button>
                                            </th>
                                            <th>
                                                Description
                                                <button onClick={() => sortUsers("DESCRIPTION")}>
                                                    sort
                                                </button>
                                            </th>
                                            <th>
                                                Online
                                                <button onClick={() => sortUsers("ONLINE")}>
                                                    sort
                                                </button>
                                            </th>
                                            <input type="text" />
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {usersList?.map((user) => {
                                            return (
                                                <tr>
                                                    <td>{user.name}</td>
                                                    <td>{user.email}</td>
                                                    <td>{user.description}</td>
                                                    {user.is_online === false ? (
                                                        <td> false </td>
                                                    ) : (
                                                        <>
                                                            {" "}
                                                            <td>true</td>{" "}
                                                        </>
                                                    )}
                                                    <td>
                                                        <Button
                                                            className={classNames("btn-simple")}
                                                            color="info"
                                                            id="deleteUser"
                                                            size="sm"
                                                            onClick={() => deleteUser(user.id, user.name)}
                                                        >
                                                            Delete
                                                        </Button>
                                                    </td>
                                                </tr>
                                            );
                                        })}
                                    </tbody>
                                </Table>
                            </CardBody>
                        </Card>
                    </Col>
                </Row>
            </div>
        </>
    );
};

export default Users;

reducer function sort code:

case "SORT":
            //Switch by sort type
            switch (action.payload.sortType) {
                case "NAME":
                    if (action.payload.sortDirection === true) {
                        sortedUsersList.sort((a, b) => (a.name > b.name ? 1 : -1));
                        return sortedUsersList;
                    } else {
                        sortedUsersList.sort((a, b) => (a.name < b.name ? 1 : -1));
                        return sortedUsersList;
                    }
                case "EMAIL":
                    if (action.payload.sortDirection === true) {
                        sortedUsersList.sort((a, b) => (a.email > b.email ? 1 : -1));
                        return sortedUsersList;
                    } else {
                        sortedUsersList.sort((a, b) => (a.email < b.email ? 1 : -1));
                        return sortedUsersList;
                    }
                case "DESCRIPTION":
                    if (action.payload.sortDirection === true) {
                        sortedUsersList.sort((a, b) =>
                            a.description > b.description ? 1 : -1
                        );
                        return sortedUsersList;
                    } else {
                        sortedUsersList.sort((a, b) =>
                            a.description < b.description ? 1 : -1
                        );
                        return sortedUsersList;
                    }

                case "ONLINE":
                    if (action.payload.sortDirection === true) {
                        sortedUsersList.sort((a, b) =>
                            a.is_online > b.is_online ? 1 : -1
                        );
                        return sortedUsersList;
                    } else {
                        sortedUsersList.sort((a, b) =>
                            a.is_online < b.is_online ? 1 : -1
                        );
                        return sortedUsersList;
                    }
            }

Going from a zoom in picture >> open a new tab

Infant coder here, used a template for my site where I wanted to showcase my work. The problem is the UX is really bad; in my portfolio section, I want the users to click on one of the images so it opens a new tab, instead of zoom in on a photo. I’ve tried to modify the JS and create a new function new tab but when I do that it stops all the other scrips on the page and no info shows up. Maybe someone on here can help? Here’s the link to the template I’ve used: https://templateflip.com/templates/super-folio/

here’s the part of the code that’s tripping me up:

 /**
   * Big Picture Popup for Photo Gallary
   */
   document.querySelectorAll(".bp-gallery a").forEach((function(e) {
    var caption = e.querySelector('figcaption')
    var img = e.querySelector('img')
    // set the link present on the item to the caption in full view
    img.dataset.caption = '<a class="link-light" target="_blank" href="' + e.href + '">' + caption.innerHTML + '</a>';
    window.console.log(caption, img)
     e.addEventListener("click", (function(t){
       t.preventDefault();
       BigPicture({
        el: t.target,
        gallery: '.bp-gallery',
      })
     })
    )
  }))

When I changed it, I did:

 /**
   * Big Picture Popup for Photo Gallary
   */
   document.querySelectorAll(".bp-gallery a").forEach((function(e) {
    var caption = e.querySelector('figcaption')
    var img = e.querySelector('img')
    function NewTab() {
        window.open(
          "a", "_blank");
    )
  }))

Which worked, but made all of the other text on the page disappear or unresponsive.

Any help you could provide would be great!

Multiple Horizontal Scroll on Datatables

As far as I know, Datatables (or any other table), cannot have two horizontal scrolls. I have added Fixed Columns from Datatables and fixed up to 6 columns out of 20 or so. The first 6 columns have taken almost 70% of the table view, so on the remaining 30%, other data cannot be seen properly.

Is there any way I can add another Horizontal Scroll on the Fixed Columns (I know this beats the purpose of fixing the columns)??

IonInput getting error with React Hook Form

Try to use a IonInput on a project.

const { register, handleSubmit, formState: { errors } } = useForm({
        
        mode: "onTouched",
        reValidateMode: "onChange"
    });

    const fields = [
        {
            label: "Firstname",
            required: true,
            requiredOptions: {

                maxLength: 10
            },
            props: {
                
                name: "firstname",
                type: "text",
                placeholder: "Enter a username"
            }
        },

        {
            label: "Age",
            required: true,
            requiredOptions: {

                min: 18,
                max: 99
            },
            props: {
                
                name: "age",
                type: "number",
                inputmode: "numeric",
                placeholder: "Enter your age"
            }
        }
    ];

    console.log(errors);
    
    const onSubmit = (data : any) => {
        
        console.log(data);
    }

    return (
        <IonPage>
            <IonHeader>
                <IonToolbar>
                    <IonTitle>React Hook Form</IonTitle>
                </IonToolbar>
            </IonHeader>
            <IonContent fullscreen>
                <IonHeader collapse="condense">
                    <IonToolbar>
                        <IonTitle size="large">React Hook Form</IonTitle>
                    </IonToolbar>
                </IonHeader>

                <IonCardSubtitle className="ion-text-center ion-margin">An example using React Hook Form</IonCardSubtitle>

                <form onSubmit={ handleSubmit(onSubmit) }>

                    { fields.map((field, index) => {

                        const { label, required, requiredOptions, props } = field;

                        return (
                            <IonItem key={ `form_field_${ index }` } lines="full">

                                <>
                                    <IonLabel position="fixed">{ label }</IonLabel>
                                    <IonInput { ...props } { ...register(props.name, { required, ...requiredOptions }) } />
                                </>
                                { required && errors[props.name] && <IonIcon icon={ alertCircleOutline } color="danger" /> }
                            </IonItem>
                        );
                    })}

                    <IonButton type="submit" className="ion-margin-top" expand="full">Submit</IonButton>
                </form>
            </IonContent>
        </IonPage>
        );

Will Get this error:

Type ‘{ onChange: ChangeHandler; onBlur: ChangeHandler; ref:
RefCallBack; name: string; min?: string | number | undefined; max?:
string | number | undefined; … 7 more …; inputmode?: undefined; }
| { …; }’ is not assignable to type ‘IntrinsicAttributes & IonInput
& Pick<HTMLAttributes, “onBlur” | “onChange” |
… 250 more … | “onTransitionEndCapture”> & StyleReactProps &
RefAttributes<…>’. Type ‘{ onChange: ChangeHandler; onBlur:
ChangeHandler; ref: RefCallBack; name: string; min?: string | number |
undefined; max?: string | number | undefined; … 7 more …;
inputmode?: undefined; }’ is not assignable to type ‘IonInput’.
Types of property ‘”max”‘ are incompatible.
Type ‘string | number | undefined’ is not assignable to type ‘string | undefined’.
Type ‘number’ is not assignable to type ‘string | undefined’.

My Dependencies:

  • @ionic/react”: “^6.0.0”
  • react-hook-form”: “^7.27.0”

I did some research through internet but didnt get a fix. May anyone help?
Moreover, are there any other forms framework are good for ionic project? Thanks!!

Calling out to an API for each element in an array

I have an array of objects. Each object is a profile of a dog including name, breed, etc. I want to be able to map through the array, get the breed of dog, and call out to an API for a random image of that breed. Below is a portion my React code that I tried (and failed). To my understanding, it’s not working because useEffect only will call out once even though I’m mapping through the array. It is possible to call out for each breed I map through?

    const urlDogBase = "https://dog.ceo/api/breed/"
    const urlEnding = "/images/random"
    const [dogImage, setDogImage] = useState({})

    let availableDogs = DogData.map((dog,index) => {
        const dogUrl = dog.breed
        const fullUrl = `${urlDogBase}${dogUrl}${urlEnding}`

        useEffect(()=>{ 
            fetch(fullUrl)
              .then((response) => response.json())
              .then((data) => setDogImage(data.message))
              .catch(() => console.log("oops error"));
          }, []);

        return(
            <img src={dogImage} />
        )
    })

React.js – How to access children’s children?

I’m trying to add more nodes to the taskRefContainer. Currently there is only one node and I’m accessing it with children but when I add an extra <div> so I can add an <input type="range" /> to that div the children obviously change. I’ve commented out the part that breaks it in the code below.

import { useState, useEffect, useRef } from "react";
import "./App.css";
import { initialTracks } from "./initialTracks";

function App() {
  const [tracks, setTracks] = useState(initialTracks);
  const [isPlaying, setIsPlaying] = useState(true);
  const tracksContainerRef = useRef();

  useEffect(() => {
    const audioContext = new (window.AudioContext ||
      window.webkitAudioContext)();
    for (const audio of tracksContainerRef.current.children) {
      audioContext
        .createMediaElementSource(audio)
        .connect(audioContext.destination);
    }
    audioContext.resume();
  }, []);
  useEffect(() => {
    for (const audio of tracksContainerRef.current.children) {
      if (isPlaying) {
        audio.pause();
      } else {
        audio.play();
      }
    }
  }, [isPlaying]);
  return (
    <div>
      <h1>Audio Mixer</h1>
      <button onClick={() => setIsPlaying(!isPlaying)}>play</button>
      <div ref={tracksContainerRef}>
        {tracks.map(({ path }, i) => (
          // <div key={i}>
          <audio key={path} src={path} />
          // <input type="range" />
          // </div>
        ))}
      </div>
    </div>
  );
}
export default App;

Why doesn’t the Canvas API support the Lucida Console font?

According to an answer in a previous question the Canvas API “allows use of any font that can otherwise be used by the user agent with a CSS stylesheet” yet while I can normally use Lucida Console in my browser it fails to load in Canvas.

Here is the font assignment that fails:

ctx.font = '15px Lucida Console, Comic Sans MS';

It has no trouble loading Comic Sans.

Or you can look at the whole example here: https://jsfiddle.net/zt6m1qeg/1/

How to pass id and store the id in variable for updating the post in redux and formik

  • How to update the Post by passing initialvalue and id in put request

    TableList.js

    import React from ‘react’;
    import { connect } from ‘react-redux’;
    import { Form, Table } from ‘react-bootstrap’;
    import { editPost, } from ‘../actions/listActions’;
    import {Formik} from ‘formik’
    import * as Yup from ‘yup’

    class TableList extends React.Component {

    componentDidMount() {
     this.props.loadTableList();
    

    }

     handleEdit = (id,list, setFieldValue) => {
     setFieldValue('name', list.name);
     setFieldValue('email', list.email);
     setFieldValue('phone', list.phone);
     setFieldValue('street', list.street);
     setFieldValue('website', list.website)
    

    }

    render() {
    const { tableList } = this.props;

     return (
         <>
       <div style={{ margin: 110 }}>
    
         <Formik 
    
         initialValues={{
         name: '',
         email: '',
         phone: '',
         website: '',
          address : {
             street: ''}
    
         }}
    
         validationSchema={validation}
    
    
         onSubmit={(initialValues)=>{
            this.props.addNewpost(initialValues);
    
         }}
    
         >
             {({errors,handleSubmit,handleChange,touched})=>(
    
                 <Form onSubmit={handleSubmit}>
                     <h3>ADD USER</h3>
                 <div>
                  <input placeholder="Name" name="name"  onChange={handleChange} />
                  {touched.name && errors.name ? (<small className='text-danger'>{errors.name}</small>) : null}
                  </div>
                <div>
                <input placeholder="Email" name="email" onChange={handleChange}/>                                                                             {touched.email && errors.email ? (<small className='text-danger'>{errors.email}  </small>) : null}
                </div>
                <div>
               <input placeholder="Phone no" name="phone" onChange={handleChange}  />
               {touched.phone && errors.phone ? (<small className='text-danger'>{errors.phone}  </small>) : null}
                  </div>
                  <div>
              <input placeholder="Website" name="website" onChange={handleChange} />
              {touched.website && errors.website ? (<small className='text-danger'>{errors.website}</small>) : null}
                </div>
                <div>
              <input placeholder="Street" name='street' onChange={handleChange} />
              {errors.street && touched.street ? (<small className='text-danger'>{errors.street}</small>) : null}
              </div>
              <div>
              <button  type='submit'  onSubmit={handleSubmit}>ADD</button>
                </div>
    
    
    
                 </Form>
    
             )        
             }
          </Formik>  
                         {tableList.map((user) => {
                             return <tr key={user.name}>
                                 <td>{user.id}</td>
                                 <td>{user.name}</td>
                                 <td>{user.email}</td>
                                 <td>{user.address.street}</td>
                                 <td>{user.phone}</td>
                                 <Link to='/'>{user.website}</Link>
                                 <td>
                                     <button onClick={() =>       this.props.deletePosts(user.id)}>Delete</button>
                                 </td>
                                 <td>
                              <button onClick={() => this.handleEdit( user.id,user,setFieldValue)}>Edit</button>
                                 </td>
                             </tr>
    
                         })}                 
    
                 </tbody>
    
                 </Table>
    
    
             </div>
         </>
     )
    

    }
    }

       const mapStateToProps = (state) => {
    return {
       tableList: get(state, ['listReducer', 'posts'], [])
    

    }
    }

       const mapDispatchToProps = (dispatch) => {
    

    return {
    updatePost: (id,name,email,phone,website)=>dispatch(editPost(id,name,email,phone,website))

    }
    }

    export default connect(mapStateToProps, mapDispatchToProps)(TableList)

    • listaction.js

    export const editPost = (id,name,email,phone,website,address)=>{
    return (dispatch)=>{

     axios.put(`https://jsonplaceholder.typicode.com/users/${id}`,name,email,phone,website,address)
    
     .then(response => {
         dispatch({
             type: actionTypes.EDIT_POST,
             payload: response.data
         })
    
         console.log(response.data);
     })
     .catch(error => {
         console.log(error);
    
     })
    

    }
    }

    • reducer.js

      case actionTypes.EDIT_POST:
      console.log(action.payload)
      return{
      …state,
      posts: action.payload,