Contract addresses are deterministic and need the deployer address and nonce to pre-compute it.
You can use the following code to determine the contract address before deployment.
const rlp = require('rlp');
const keccak = require('keccak');
const web3 = require('web3')
const encodedData = rlp.encode([
'0x6c4465dc4dc3466c5736142ce8e12917a1e22c4', // address from which contract is to be deployed
web3.utils.toHex(4) // hex encoded nonce of address that will be used for contract deployment
]);
const contractAddress = 0x${keccak('keccak256').update(encodedData).digest('hex').substring(24)}
console.log({contractAddress}
But I will recommend adding a method in the second contract and update the contract address later. Make sure that the function is callable only once, this will be a more reliable approach.
Sample code:
pragma solidity 0.6.8;
contract A {
address b;
function addSecondaryContract(address _b) public /* onlyOwner */ {
require(b != address(0), "contract already added");
b = _b;
}
}
contract B {
address a;
constructor(address _a) public{
a = _a;
}
}