Trying to upload a ScreenCapture Video (JavaScript) onto a server (Java)

i wanted to write a javascript function that records the screen of the user and saves it onto a server.

It seems to work so far and records the user-selected screen (i printed most variables into the console for testing purpose but here deleted it for clarity, the ids etc are filled), but there is a problem when i am trying to upload it.

Since i am new to JavaScript programming, i seem to be stuck now, i tried to change mimeTypes/types in ajax since i am not sure if they are used right, did not help.

I run the JavaScript frontend on a local XAMPP and the Java backend on a local WildFly.

Would be so glad if anyone got helping ideas.

The code i wrote is integrated into a existing project, i will post the snippets i wrote.

1)

 // Create Recorder

var recorder;
var stream;
var chunks = [];
var blob = new Blob;
var start_recording_timestamp ;


this.startIntegratedScreenCapture = async function () {

    start_recording_timestamp = new Date(new Date().getTime() + 3600000).toISOString(); //add 1 hour because of Berlin-Timezone

   try {
        stream = await navigator.mediaDevices.getDisplayMedia({
            video: {mediaSource: "screen"},
            mimeType: 'video/webm;codecs=h264'
        });

    recorder = new MediaRecorder(stream);

    recorder.ondataavailable = e => chunks.push(e.data);
    recorder.onstop = e => {
        let that = this;
        blob = new Blob(chunks, { type: chunks[0].type });
      
        window.repositoryService.saveVideoForModel(window.modelId, start_recording_timestamp, blob);
        that.videoSaveCallbacks.forEach(callback => callback(blob));
    };

    recorder.start();

    }
    catch(e){console.log(e)}
};
     //stop Recording



 this.stopIntegratedScreenCapture = function () {
    if (recorder) {
  recorder.stop();
  stream.getVideoTracks()[0].stop();
    }

};
  // Integrated Screen Capture



this.saveVideoForModel = function (modelID, timestamp, video_content) {

    var reader = new  FileReader();

    reader.addEventListener('loadend', (event) => {
        var videoAsJSON = event.srcElement.result;
        var videoURI = this.videoURI;

        var data = new FormData();
      data.append("data", new Blob([videoAsJSON], {type: "application/octet-stream"}));
        data.append("modelID", modelID);
        data.append("startRecTimestamp", timestamp);


        this.uploadVideo("POST", videoURI, data, function (response) {
            try {
                response = JSON.parse(response);
            } catch (event) {
            }
            if (response === null || response === "") {
                window.showMessage("Error saving the video", "error", "Error");
                return;
            }
            window.showMessage("Video of model " + modelID + " successfully saved", "success", "Success");
        },function (error){console.log(error)});

    });

    reader.readAsArrayBuffer(video_content);
};
  1. //start upload
    
    
    
    
     this.uploadVideo = function (method, url, data, success, error) {
      var errorHandler = (error != null) ? error : this.defaultErrorHandler;
      var token = this.getToken();
      url = method === "DELETE" ? url + "?" + $.param(data) : url;
    
    
      $.ajax({
          url: url,
          type: method,
          data: data,
          enctype: 'multipart/form-data',
          cache: false,
          async: true,
          processData: false,
          contentType: false,
          beforeSend: function (xhr) {
              if (token != null) {
                  xhr.setRequestHeader("Authentication", "Bearer" + token);
              }
          },
          success: success,
          error: errorHandler
      }
      ).done(function(data){console.log(data)});
    

    };

The serverside code looks like this, it uses Spring framework:

    @CrossOrigin(origins = "*")
    @RequestMapping(value = "/integrated/saveVideo", method = 
     RequestMethod.POST)
     public ResponseEntity<VideoDto> saveVideo(@RequestParam("data") 
      MultipartFile file,
                                          @RequestParam("modelID") 
      String modelID,
                                          
     @RequestParam("startRecTimestamp") String startRecTimestamp) {
    HttpStatus status = HttpStatus.OK;
    startRecTimestamp = startRecTimestamp.replaceAll(":", "_");
    String fileName = env.getProperty("screenrecording.directory") + 
    modelID + "_Model_" + startRecTimestamp;
    try (FileOutputStream fosVideo = new FileOutputStream(fileName, 
   true)){
        byte[] bytes = file.getBytes();
        fosVideo.write(bytes);
    } catch (IOException ioe) {
        status = HttpStatus.CONFLICT;
        ioe.printStackTrace();
    }
    return new ResponseEntity<>(new VideoDto(), status);
}   

When i use developer mode in firefox, i see that the program seems to fail at the axaj query (the beforeSend in the ajax gets triggered, tried it with console.log to see if token has id)

The FunctionReponse gets not triggered using uploadVideo function in saveVideoForModel since uploadVideo function ends in error.

       Status
       409
         Conflict
       VersionHTTP/1.1
   Referrer Policystrict-origin-when-cross-origin

XHRPOST../saveVideo
[HTTP/1.1 409 Conflict 610ms]

POST
…/saveVideo
Status
409
Conflict
VersionHTTP/1.1
Übertragen533 B (81 B Größe)
Referrer Policystrict-origin-when-cross-origin

HTTP/1.1 409 Conflict

Expires: 0

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

X-XSS-Protection: 1; mode=block

Pragma: no-cache

X-Frame-Options: DENY

Date: Mon, 29 Nov 2021 23:31:07 GMT

Connection: keep-alive

Access-Control-Allow-Origin: *

Vary: Origin

Vary: Access-Control-Request-Method

Vary: Access-Control-Request-Headers

X-Content-Type-Options: nosniff

Transfer-Encoding: chunked

Content-Type: application/json; charset=UTF-8








   XHRPOST.../saveVideo
   [HTTP/1.1 409 Conflict 610ms]

    
   POST
    .../saveVideo
  Status
   409
  Conflict
   VersionHTTP/1.1
  Übertragen533 B (81 B Größe)
   Referrer Policystrict-origin-when-cross-origin
        
    HTTP/1.1 409 Conflict

    Expires: 0

    Cache-Control: no-cache, no-store, max-age=0, must-revalidate

    X-XSS-Protection: 1; mode=block

    Pragma: no-cache

    X-Frame-Options: DENY

    Date: Mon, 29 Nov 2021 23:31:07 GMT

    Connection: keep-alive

    Access-Control-Allow-Origin: *

    Vary: Origin

    Vary: Access-Control-Request-Method

    Vary: Access-Control-Request-Headers

    X-Content-Type-Options: nosniff

    Transfer-Encoding: chunked

    Content-Type: application/json; charset=UTF-8
        
    POST ...saveVideo HTTP/1.1

    Host: localhost:8080

    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0

    Accept: */*

    Accept-Language: de,en-US;q=0.7,en;q=0.3

    Accept-Encoding: gzip, deflate

    Authentication: BearereyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJwcm9iYW5kIiwiZXhwIjoxNjM4Mjc1ODU0fQ.dy-e-gJtD3R-UlPD9FVnJ5YQmjko7tEqS-l9ocprk9vRpCXUKjelL78mafe9zTKJlDo_c8pElbiQWKdGIbfapw

    Content-Type: multipart/form-data; boundary=---------------------------188953772220050190214011980307

    Content-Length: 1090343

    Origin: http://localhost

    Connection: keep-alive

    Referer: http://localhost/

    Sec-Fetch-Dest: empty

    Sec-Fetch-Mode: cors

    Sec-Fetch-Site: cross-site

JSON is not properly turning an object into a string

I am making a game and am working on the accounts. When i have JSON stringify the object and save it to a file, it sometimes (occasionally and at random) writes:

{"[email protected]":{"email":"[email protected]","password":"myPassword","token":"c26a2a66-77f8-43d7-aa92-14da81979386"} >}< "[email protected]":{"email":"[email protected]","password":"myPassword","token":"209758d0-9a6e-4e99-835a-21595b822796"}}

when i am expecting:

{"[email protected]":{"email":"[email protected]","password":"myPassword","token":"c26a2a66-77f8-43d7-aa92-14da81979386"} >,< "[email protected]":{"email":"[email protected]","password":"myPassword","token":"209758d0-9a6e-4e99-835a-21595b822796"}}

My Code:

fs.writeFile('save_info/users.json', JSON.stringify(User.USERS), err => {});

What is going on?

How Node JS Map Of Values Adds Up to K

Given a list of numbers const arr = [{ key1: 10 }, { key2: 5 }, { key3: 7 }, { key4: 17 }];and a number k say const k = 17;, return whether any two numbers from the list add up to k. For example, given [10, 15, 3, 7] and k = 17, we should return True, since 10 + 7 =17.

Wrote below code using key,values in Map,but seems not able to get the solution,can anyone suggest what code change is needed below ,want to solve especially using Maps

const arr = [{ key1: 10 }, { key2: 5 }, { key3: 7 }, { key4: 17 }];
const k = 17;
let addInput = new Map(arr.flatMap((x) => Object.entries(x)));

addInput.forEach((v) => {
  for (var i = 0; i < addInput.size; i++) {
    if (v != addInput[i]) {
      if (addInput[i] + v == k) {
        console.log(`${v} + ${addInput[i]} = ${k} (true)`);
      }
    }
  }
});

Sort by date with isotope-layout in Next js

I can’t find any documentation on how to do a date sort with isotope-layout in my Next JS project. Here is how far I have got.
The date obviosuly sorts but it will sort alphabetically. I need to know how to write this in
date: function ($elem) { return Date.parse($elem.find('.date').text()); }

const KeyOutcomes = (props) => {
  const isotope = useRef()
  const [sortKey, setSortKey] = useState('date')

  // initialize an Isotope object with configs
  useEffect(() => {
    isotope.current = new Isotope('.news', {
      itemSelector: '.newsInner',
      layoutMode: 'fitRows',
      getSortData: {
        header: '.header',
        date: '.date',
      },
    })
    // cleanup
    return () => isotope.current.destroy()
  }, [])

  // handling sort key change
  useEffect(() => {
    isotope.current.arrange({ sortBy: `${sortKey}` })
  }, [sortKey])

  const handleSortKeyChange = (key) => () => setSortKey(key)
  return (
    <div className="container">
      <div className="row">
        <div className="col-12">
          <div className="sortAndFilter">
            <ul className="sortFilter">
              <li>Sort By:</li>
              <li
                onClick={handleSortKeyChange('header')}
              >
                Header
              </li>
              <li
                onClick={handleSortKeyChange('date')}
              >
                Date
              </li>
            </ul>
          </div>
          <div className="news">
            <div className="newsInner vege">
              <div className="newsText two">
                <h3 className="header">V News Header</h3>
                <p className="date">02/05/2020</p>
              </div>
            </div>
            <div className="newsInner one">
              <div className="newsText">
                <h3 className="header">D News Header</h3>
                <p className="date">26/05/2020</p>
              </div>
            </div>
            <div className="newsInner one">
              <div className="newsText">
                <h3 className="header">G News Header</h3>
                <p className="date">10/12/2021</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

React state not updating after API request

I am making a very simple store front react app that talks to a simple backend API that I made. I am trying to make a cart system that makes a POST request using the Axios library each time the page is loaded. The API will send back a cart object and it will have a unique ID. I want to store this ID in a state so that I can pass it to other pages to track the current card.

Here is the code for the function that handles making a POST request with Axios and storing that data in the currentCartID state:

const makeAPIPOSTRequestForCart = () => {
        setAPIRequestIsLoading(true);
        Axios.post('http://localhost:5512/carts/create').then((response) => {
            setCurrentCardID(response.data._id); // <-- THIS IS THE SET METHOD FOR THE STATE
            console.log('====================================');
            console.log('STATUS: ' + response.status);
            console.log('ID: ' + response.data._id);
            console.log('STATE OBJ: ' + currentCartID); // <--- PRINTS OUT NOTHING OR UNDEFINED
            console.log('====================================');
            setAPIRequestIsLoading(false);
        });
    };

This function is called each time the page is loaded with the useEffect hook like so:

useEffect(() => {
        makeAPIGETRequest();
        if (isCartMade === false) {
            makeAPIPOSTRequestForCart(); // <--- CALL TO POST FUNCTION RIGHT HERE
            setIsCartMade(true);
        }
    }, []);

The problem is each time I make this request the API is responding with a cart object and I can view the ID, however I cant seem to set the state to the current ID which is a string. Ive made sure that the type is correct however nothing is working. Whenever I try printing the state all I get is undefined or a blank line. It seems that the update state function is not working properly.

I am quite new to react so any help would be greatly appreciated! 🙂

Ethers contract on method “No mathing event” error

I just started learning ethers, here is my code:

(async () => {
  const connection = new ethers.providers.JsonRpcProvider(
    "https://mainnet.infura.io/v3/key"
  );

  const contract = new ethers.Contract(
    "0x7be8076f4ea4a4ad08075c2508e481d6c946d12b",
    abi,
    connection
  );

  contract.on("atomicMatch_", (to, amount, from) => {
    console.log(to, amount, from);
  });
})();

so the contract is opensea main contract – link
I would like to listen to sales transactions/events. As I see in the contract name of that event is probably Atomic Match_ or atomicMatch_ in ABI.
For ABI I just copy pasted whole contract to https://remix.ethereum.org/ website and copied abi code. The problem is I am getting this error now:

Error: no matching event (argument="name", value="atomicMatch_", code=INVALID_ARGUMENT, version=abi/5.5.0)

What is wrong here? I tried both names of event but I get the same error over and over…

javascript tip calculator output not showing on html page

So I seem to have this issue a lot with my output not showing on the html, and even following along previous programs seems to give me no clue on why they never show. But I have a simple tip calculate program in javascript, I want the tip amount and tip per person to appear under the form on the html page, but whenever I hit the submit button nothing appears. I tried different event listeners (both visible in the code) one on the button and one in the javascript but it did nothing. I’m not sure if it’s due to the “” around the submit in html and the ” around submit in javascript, or even if I’m supposed to use ” around the ids in the html, I saw different code using either or so I was uncertain on which to really use so I went with “” around the ids in the html file.

HTML (filename pro3):

<!DOCTYPE html>
<html>
    <head>
        <title>Project 3</title>
    </head>

    <body>
        <script src = "pro3java.js"></script>

        <h1>TIP CALUCULATOR</h1>

        <form name = 'tipForm'>
            <p>Enter bill amount:</p>
            <input type="number"name="billAmt">

            <br>

            <p>Enter tip percentage:</p>
            <input type="number" name="tipPerc">

            <br>

            <p>Enter number of people:</p>
            <input type="number" name="people">

            <br>
            <br>
            
            <button type="submit" onclick="result()">Calculate</button>
            <br>
        </form>

        <div id = 'tipResult'></div>
        
    </body>
</html>

JAVASCRIPT (filename pro3java:

const form = document.forms.tipForm;

const output = document.getElementById('#tipResult');

form.addEventListener('submit', result);

//calc
let tip = parseInt(form.bill.value) * (parseInt(form.tipPerc.value) / 100);

let amount = (parseInt(form.bill.value) + parseInt(tip)) / form.people.value;

let total = amount.toFixed(2);

function result(e){
tipResult.textContent = `Your tip is $${tip}!`;
tipResult.textContent = `Everyone will pay $${total}!`;
} //result end

Cypress E2E Testing how can i make cypress use windows authentication where i do not have any specific login API request

Am stuck at an issue where am unable to make use of cy.ntlmSs and cy.ntlm to launch my work url. This application uses Windows Authentication which is collected by .net core pre-defined library and does use any login validation via API call with username and password.

How do overcome this scenario. I have tried almost all available ntlm options but none work. Please suggest.

need to check input form if user upload the file or not with javascript

i have input form to upload you file and submitting that file(method = post) i need to cheack if user upload the image or not. if not should display error message and return false. but in my case return false don’t working

my code

const jobs = document.getElementById("jobImage");
const error = document.getElementById("Error");

my function

function func(){
    if(jobs.value < 1){    
     console.log("1")
     error.style.display = "block";
     error.textContent = "Pleas upload your image";
     setTimeout(function(){ window.location.reload(); },5000);
      return false
    }
        
}

when i use my function its return true not false

<div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <button  type="submit" value="Save" class="btn btn-default" id="save" onclick="func()"><a href="www.google.com">Go now</a></button>
        </div>
    </div>
</div>

best regards

How can I stop this document attached event listener from emitting duplicate events?

I’d like for a game to fire events upon key presses, but when I navigate away from and back to the game page the event listener fires twice. I found another issue suggesting I remove the listener before adding it, but that isn’t helping.

The listener is added during mounted

mounted() {
        this.setupInputListener();
    },

And the keydown event listener is added to the document

        keydownListener() {
            const action = handleKeyDown(event.key);
            if ( action ) {
                this.SEND_INPUT({
                    gameId: this.gameId,
                    action: action
                });
            }
        },
        setupInputListener() {
            document.removeEventListener('keydown', this.keydownListener);
            document.addEventListener('keydown', this.keydownListener);
        }

How can I prevent this keydown listener from emitting duplicate events?

jquery select multiple options show and hide input type number with placeholder

<div class="form-group"><label for="unit_of">Unit of Measure</label>
<select class="form-control-sm selectpicker" multiple="multiple" id="unit_of" name="unit_of[]" data-selected-text-format="count">
<?php $sql = "select * from unit_of";
$res = mysqli_query($db_handle, $sql);
while ($list = mysqli_fetch_assoc($res)) {
$unit_of = $list['unit_of'];
?>
<option><?= $unit_of; ?></option>
<?php
}
?>
</select>
</div>
<input type="text" class="form-control-sm" id="rates" name="rates" >
<input type="text" class="form-control-sm" id="rates1" name="rates1" style="display:none">
<input type="text" class="form-control-sm" id="rates2" name="rates2" style="display:none">

In the dropdown
Per Minute
Per Page,
Per Hour,
Per Day,
Per Month,
Per Item,
Per Contract,
Others

I want to add onchange multiple select max three input types number on multiple select with placeholder e.g.(“Enter Rate Per Page”)

Thanks in Advance

How to change a nested object value of a redux state

I have the following state

const state = {
  courses: [],
  series: [],
  course: {
      title: 'testing',
      course_notes: [
    {
      id: 1,
      note: "one" // want to edit this
    },
    {
      id: 2,
      note: "two"
    }
  ]
}
}

I want to change state.course.course_notesp[0].name

I’ve never fully understood how this works, read a lot of tutorials, I feel I know how it works but it always trips me up. This is what I am trying

const m = {
  ...state, 
  course: {
    course_notes:[
      ...state.course.course_notes,
      state.course.course_notes.find(n => n.id === 1).note = "edited"
    ]
  }
}

That seems to add edited as an extra node. state.course.course_notes.length ends up being 3.

React testing library – TypeError: (0 , _axios.default) is not a function when using axios util that returns axios(config)

Im trying to write some unit test for my React app, and still in the process of getting familiar with the React testing library.

I created an empty page to just test on the axios api calls to make myself familiar with it. I have a axios util for customize basicAxios. When I follow the step for axios testing I got the typeError mentioned on the title.

here is my axios util code:

// axiosUtils.ts
import axios from "axios";
import { merge } from "lodash";
import type { AxiosPromise } from "axios";
import { getToken } from "./authUtils";

export const basicAxios = (options: {}): AxiosPromise<any> => {
  const token = getToken();
  const config = merge({ params: { token } }, options);
  return axios(config);
};

here is the test component:

// TestPage.tsx
const TestPage = () => {
  const [total, setTotal] = useState<number | null>(null);

  useEffect(() => {
    basicAxios({
      method: "POST",
      url: URL,
      data: payloadBody,
    }).then(({ data }) => {
      setTotal(data.total);
    });

    // async function getSummary() {
    //   try {
    //     const { data } = await axios.post(URL, payloadBody);
    //     setTotal(data.total);
    //   } catch (error) {
    //     console.log(error);
    //   }
    // }

    // getSummary();
  }, []);

  return (
    <Container>
      {!total ? (
        <Loader>Loading...</Loader>
      ) : (
        <div>
          Total amount of return:
          <Label data-testid="label">{total}</Label>
        </div>
      )}
    </Container>
  );
};

export default TestPage;

here is my jest setup to mock axios:

//axios.ts
export default {
  __esModule: true,
  post: jest.fn().mockResolvedValue({ data: {} }),
  get: jest.fn().mockResolvedValue({ data: {} }),
  default: jest.fn().mockResolvedValue({ data: {} }),
};

Lastly here is my test file:

// TestPage.test.tsx
import React from "react";
import { render } from "@testing-library/react";
import axios from "axios";
import "@testing-library/jest-dom/extend-expect";
import TestPage, { URL, payloadBody } from "../TestPage";

const mockedAxios = axios as jest.Mocked<typeof axios>;

test("show loader when it's fetching data, then render total num", async () => {
  mockedAxios.post.mockResolvedValueOnce({
    data: {
      aggregations: [],
      total: 144,
    },
  });

  const { findByTestId, getByText } = render(<TestPage />);

  expect(getByText(/loading.../i)).toBeInTheDocument();

  const labelValue = await findByTestId("label");

  expect(mockedAxios.post).toHaveBeenCalledWith(URL, payloadBody);
  expect(mockedAxios.post).toHaveBeenCalledTimes(1);
});

In my TestPage.tsx, if I use the comment-out code, the test pass without the error. The error occurs when I use basicAxios(used in multiple places in the app).
Below is the error log:

TypeError: (0 , _axios.default) is not a function

       9 |   const token = getToken();
      10 |   const config = merge({ params: { token } }, options);
    > 11 |   return axios(config);
         |          ^
      12 | };
      13 |

      at basicAxios (src/lib/axiosUtils.ts:11:10)
      at src/features/pages/TestPage.tsx:22:5
      at invokePassiveEffectCreate (node_modules/react-dom/cjs/react-dom.development.js:23487:20)
      at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14)
      at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
      at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
      at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
      at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16)
      at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31)
      at flushPassiveEffectsImpl (node_modules/react-dom/cjs/react-dom.development.js:23574:9)
      at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12)
      at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10)
      at flushPassiveEffects (node_modules/react-dom/cjs/react-dom.development.js:23447:14)
      at Object.<anonymous>.flushWork (node_modules/react-dom/cjs/react-dom-test-utils.development.js:992:10)
      at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1107:9)
      at render (node_modules/@testing-library/react/dist/pure.js:82:26)
      at Object.<anonymous> (src/features/pages/__test__/TestPage.test.tsx:19:39)

Does anyone have experience on this issue?

setInterval setting this to window instead of class (calling class function)

render() {
    drawRect(0,0,canvas.width,canvas.height,3);
    console.log(this) // when called with setInterval(classObject.render, 1000), returns window; if called with (classObject).render returns (classObject)
    for (let i = 0; i <= this.sprites.length; i++) {
        if (this.sprites[i]) {
            let cs = this.sprites[i]
            cs.drawRoutine(cs.position.x,cs.position.y);
        }
    }
}
setRenderInterval(fps) {
    setInterval(this.render,1000/fps);
}

Here, let’s assume classObject is called game.
When game.render() is called normally, it has game as this. But when it’s called using setInterval, it has window as this. How can I circumvent this?
this.sprites is an array of sprites for the game, and it needs to be accessed using this, as there can be multiple games with different variable names. And cs.drawRoutine is a function within the sprite that just draws in the canvas. The function runs when normally called.