问:
React Native + WebRTC TypeError: Undefined is not and Object(Evaluating: 'data.type')
I've been trying to learn WebRTC with React Native, so I've been working on this video call project. I thought I had it all figured out until this came up.

First of all, this is my React Native Code

```<code>import React, {useEffect, useState, useCallback} from 'react';
import {View, StyleSheet, Alert} from 'react-native';
import {Text} from 'react-native-paper';
import {Button} from 'react-native-paper';
import AsyncStorage from '@react-native-community/async-storage';
import {TextInput} from 'react-native-paper';

import {useFocusEffect} from '@react-navigation/native';

import InCallManager from 'react-native-incall-manager';

import {
  RTCPeerConnection,
  RTCIceCandidate,
  RTCSessionDescription,
  RTCView,
  MediaStream,
  MediaStreamTrack,
  mediaDevices,
  registerGlobals,
} from 'react-native-webrtc';

export default function CallScreen({navigation, ...props}) {
  let name;
  let connectedUser;
  const [userId, setUserId] = useState('');
  const [socketActive, setSocketActive] = useState(false);
  const [calling, setCalling] = useState(false);
  // Video Scrs
  const [localStream, setLocalStream] = useState({toURL: () => null});
  const [remoteStream, setRemoteStream] = useState({toURL: () => null});
  const [conn, setConn] = useState(new WebSocket('ws://:4443/'));
  const [yourConn, setYourConn] = useState(
    new RTCPeerConnection({
      iceServers: [
        {
          urls: 'stun:stun.l.google.com:19302',
        }, {
          urls: 'stun:stun1.l.google.com:19302',
        }, {
          urls: 'stun:stun2.l.google.com:19302',
        }, {
          username: "",
          credential: "",
          urls: 'turn::3478',
        }, {
          username: "",
          credential: "",
          urls: 'stun::3478',
        }
      ],
    }),
  );

  const [offer, setOffer] = useState(null);

  const [callToUsername, setCallToUsername] = useState(null);

  useFocusEffect(
    useCallback(() => {
      AsyncStorage.getItem('userId').then(id => {
        console.log(id);
        if (id) {
          setUserId(id);
        } else {
          setUserId('');
          navigation.push('Login');
        }
      });
    }, [userId]),
  );

  useEffect(() => {
    navigation.setOptions({
      title: 'Hola' + userId,
      headerRight: () => (
        <Button mode="text" onPress={onLogout} style={{paddingRight: 10}}>
          Salir
        </Button>
      ),
    });
  }, [userId]);

  useEffect(() => {
    if (socketActive && userId.length > 0) {
      try {
        InCallManager.start({media: 'audio'});
        InCallManager.setForceSpeakerphoneOn(true);
        InCallManager.setSpeakerphoneOn(true);
      } catch (err) {
        console.log('InApp Caller ---------------------->', err);
      }

      console.log(InCallManager);

      send({
        type: 'login',
        name: userId,
      });
    }
  }, [socketActive, userId]);

  const onLogin = () => {};

  useEffect(() => {

    conn.onopen = () => {
      console.log('Connected to the signaling server');
      setSocketActive(true);
    };
    conn.onmessage = msg => {
      let data;
      if (msg.data === 'Hello world') {
        data = {};
      } else {
        dcata = JSON.parse(msg.data);
        console.log('Data --------------------->', data);
        switch (data.type) {
          case 'login':
            console.log('Login');
            break;
          case 'offer':
            handleOffer(data.offer, data.name);
            console.log('Offer');
            break;
          case 'answer':
            handleAnswer(data.answer);
            console.log('Answer');
            break;
          case 'candidate':
            handleCandidate(data.candidate);
            console.log('Candidate');
            break;
          case 'leave':
            handleLeave();
            console.log('Leave');
            break;
          default:
            break;
        }
      }
    };
    conn.onerror = function(err) {
      console.log('Got error', err);
    };

    let isFront = false;
    mediaDevices.enumerateDevices().then(sourceInfos => {
      let videoSourceId;
      for (let i = 0; i < sourceInfos.length; i++) {
        const sourceInfo = sourceInfos[i];
        if (
          sourceInfo.kind == 'videoinput' &&
          sourceInfo.facing == (isFront ? 'front' : 'environment')
        ) {
          videoSourceId = sourceInfo.deviceId;
        }
      }
      mediaDevices
        .getUserMedia({
          audio: true,
          video: {
            mandatory: {
              minWidth: 500,
              minHeight: 300,
              minFrameRate: 30,
            },
            facingMode: isFront ? 'user' : 'environment',
            optional: videoSourceId ? [{sourceId: videoSourceId}] : [],
          },
        })
        .then(stream => {
          setLocalStream(stream);

          yourConn.addStream(stream);
        })
        .catch(error => {

        });
    });

    yourConn.onaddstream = event => {
      console.log('On Add Stream', event);
      setRemoteStream(event.stream);
    };

    yourConn.onicecandidate = event => {
      if (event.candidate) {
        send({
          type: 'candidate',
          candidate: event.candidate,
        });
      }
    };
  }, []);

  const send = message => {
    if (connectedUser) {
      message.name = connectedUser;
      console.log('Connected iser in end----------', message);
    }

    conn.send(JSON.stringify(message));
  };

  const onCall = () => {
    setCalling(true);

    connectedUser = callToUsername;
    console.log('Caling to', callToUsername);

    yourConn.createOffer().then(offer => {
      yourConn.setLocalDescription(offer).then(() => {
        console.log('Sending Ofer');
        console.log(offer);
        send({
          type: 'offer',
          offer: offer,
        });
      });
    });
  };

  const handleOffer = async (offer, name) => {
    console.log(name + ' is calling you.');

    console.log('Accepting Call===========>', offer);
    connectedUser = name;

    try {
      await yourConn.setRemoteDescription(new RTCSessionDescription(offer));

      const answer = await yourConn.createAnswer();

      await yourConn.setLocalDescription(answer);
      send({
        type: 'answer',
        answer: answer,
      });
    } catch (err) {
      console.log('Offerr Error', err);
    }
  };

  const handleAnswer = answer => {
    yourConn.setRemoteDescription(new RTCSessionDescription(answer));
  };

  const handleCandidate = candidate => {
    setCalling(false);
    console.log('Candidate ----------------->', candidate);
    yourConn.addIceCandidate(new RTCIceCandidate(candidate));
  };

  const hangUp = () => {
    send({
      type: 'leave',
    });

    handleLeave();
  };

  const handleLeave = () => {
    connectedUser = null;
    setRemoteStream({toURL: () => null});

    yourConn.close();

  };

  const onLogout = () => {

    AsyncStorage.removeItem('userId').then(res => {
      navigation.push('Login');
    });
  };

  const acceptCall = async () => {
    console.log('Accepting Call===========>', offer);
    connectedUser = offer.name;

    try {
      await yourConn.setRemoteDescription(new RTCSessionDescription(offer));

      const answer = await yourConn.createAnswer();

      await yourConn.setLocalDescription(answer);

      send({
        type: 'answer',
        answer: answer,
      });
    } catch (err) {
      console.log('Offerr Error', err);
    }
  };
  const rejectCall = async () => {
    send({
      type: 'leave',
    });
    ``;
    setOffer(null);

    handleLeave();
  };

  return (
    <View style={styles.root}>
      <View style={styles.inputField}>
        <TextInput
          label="Ingresa el ID del familiar"
          mode="outlined"
          style={{marginBottom: 7}}
          onChangeText={text => setCallToUsername(text)}
        />
        <Button
          mode="contained"
          onPress={onCall}
          loading={calling}
          //   style={styles.btn}
          contentStyle={styles.btnContent}
          disabled={!(socketActive && userId.length > 0)}>
          Llamar
        </Button>
      </View>

      <View style={styles.videoContainer}>
        <View style={[styles.videos, styles.localVideos]}>
          <Text>Tu video</Text>
          <RTCView streamURL={localStream.toURL()} style={styles.localVideo} />
        </View>
        <View style={[styles.videos, styles.remoteVideos]}>
          <Text>Video del familiar</Text>
          <RTCView
            streamURL={remoteStream.toURL()}
            style={styles.remoteVideo}
          />
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  root: {
    backgroundColor: '#fff',
    flex: 1,
    padding: 20,
  },
  inputField: {
    marginBottom: 10,
    flexDirection: 'column',
  },
  videoContainer: {
    flex: 1,
    minHeight: 450,
  },
  videos: {
    width: '100%',
    flex: 1,
    position: 'relative',
    overflow: 'hidden',

    borderRadius: 6,
  },
  localVideos: {
    height: 100,
    marginBottom: 10,
  },
  remoteVideos: {
    height: 400,
  },
  localVideo: {
    backgroundColor: '#f2f2f2',
    height: '100%',
    width: '100%',
  },
  remoteVideo: {
    backgroundColor: '#f2f2f2',
    height: '100%',
    width: '100%',
  },
});
</code>```

At this point is worth to mention that my STUN/TURN server works perfectly, and this is my signaling socket

```<code>var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer({port: 4443});
var users = {};

wss.on('connection', function(connection) {

   console.log('User connected');

   //when server gets a message from a connected user
   connection.on('message', function(message) {

      var data;
      //accepting only JSON messages
      try {
         data = JSON.parse(message);
      } catch (e) {
         console.log('Invalid JSON');
         data = {};
      }

      //switching type of the user message
      switch (data.type) {
         //when a user tries to login

         case 'login':
            console.log('User logged', data.name);

            //if anyone is logged in with this username then refuse
            if(users[data.name]) {
               sendTo(connection, {
                  type: 'login',
                  success: false
               });
            } else {
               //save user connection on the server
               users[data.name] = connection;
               connection.name = data.name;

               sendTo(connection, {
                  type: 'login',
                  success: true
               });
            }

            break;

         case 'offer':
            //for ex. UserA wants to call UserB
            console.log('Sending offer to: ', data.offer, data.name);

            //if UserB exists then send him offer details
            var conn = users[data.name];

            if(conn != null) {
               //setting that UserA connected with UserB
               connection.otherName = data.name;

               sendTo(conn, {
                  type: 'offer',
                  offer: data.offer,
                  name: connection.name
               });
            }

            break;

         case 'answer':
            console.log('Sending answer to: ', data.answer);
            //for ex. UserB answers UserA
            var conn = users[data.answer];

            if(conn != null) {
               connection.otherName = data.name;
               sendTo(conn, {
                  type: 'answer',
                  answer: data.answer
               });
            }

            break;

         case 'candidate':
            console.log("Sending candidate to:",data.name);
            var conn = users[data.name];

            if(conn != null) {
               sendTo(conn, {
                  type: 'candidate',
                  candidate: data.candidate
               });
            }

            break;

         case 'leave':
            console.log('Disconnecting from', data.name);
            var conn = users[data.name];
            conn.otherName = null;

            //notify the other user so he can disconnect his peer connection
            if(conn != null) {
               sendTo(conn, {
                  type: 'leave'
               });
            }

            break;

         default:
            sendTo(connection, {
               type: 'error',
               message: 'Command not found: ' + data.type
            });

            break;
      }
   });

   //when user exits, for example closes a browser window
   //this may help if we are still in "offer","answer" or "candidate" state
   connection.on('close', function() {

      if(connection.name) {
      delete users[connection.name];

         if(connection.otherName) {
            console.log('Disconnecting from ', connection.otherName);
            var conn = users[connection.otherName];
            conn.otherName = null;

            if(conn != null) {
               sendTo(conn, {
                  type: 'leave'
               });
            }
         }
      }
   });

   connection.send('Hello world');

});

function sendTo(connection, message) {
   connection.send(JSON.stringify(message));
}
</code>```

But here si where the problems begin.

When I use the App to login this is what the Socket shows.

```<code>User connected
User connected
User connected
User logged 1
User connected
User connected
User connected
User connected
User connected
</code>```

But immediately, the app shows this.

And if I dismiss the error and try to Call another peer that is already conected, the error shows on the device I try to Call.

The React Native cli, tells me the same as the error

```<code>Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.
[Tue Jun 02 2020 10:34:26.400]  LOG      Running "webrtcApp" with {"rootTag":1}
[Tue Jun 02 2020 10:37:20.365]  LOG      Connected to the signaling server
[Tue Jun 02 2020 10:37:20.487]  LOG      1
[Tue Jun 02 2020 10:37:20.747]  LOG      {"audioUriMap": {"busytone": {"_BUNDLE_": null, "_DEFAULT_": null}, "ringback": {"_BUNDLE_": null, "_DEFAULT_": null}, "ringtone": {"_BUNDLE_": null, "_DEFAULT_": null}}, "cameraPermission": "granted", "checkCameraPermission": [Function bound checkCameraPermission], "checkRecordPermission": [Function bound checkRecordPermission], "recordPermission": "granted", "requestCameraPermission": [Function bound requestCameraPermission], "requestRecordPermission": [Function bound requestRecordPermission], "vibrate": false}
[Tue Jun 02 2020 10:37:20.914]  LOG      1
[Tue Jun 02 2020 10:37:20.933]  LOG      Data ---------------------> undefined
[Tue Jun 02 2020 10:37:52.746]  LOG      Data ---------------------> undefined
</code>```

And here it is what the socket shows when I try to call another peer that is Connected.

```<code>Sending offer to:  {
  sdp: 'v=0\r\n' +
    'o=- 3903065942025360998 2 IN IP4 127.0.0.1\r\n' +
    's=-\r\n' +
    't=0 0\r\n' +
    'a=group:BUNDLE audio video\r\n' +
    'a=msid-semantic: WMS 4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 102 0 8 106 105 13 110 112 113 126\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:+CFh\r\n' +
    'a=ice-pwd:ccPSGw5U3fnoHysgp1bquCYJ\r\n' +
    'a=ice-options:trickle renomination\r\n' +
    'a=fingerprint:sha-256 2A:2B:C1:A4:1D:8C:B3:C3:B8:AA:6D:C2:36:71:F7:95:61:CC:54:E6:2D:79:C0:4D:A5:D4:E1:45:3D:00:BF:F4\r\n' +
    'a=setup:actpass\r\n' +
    'a=mid:audio\r\n' +
    'a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n' +
    'a=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=sendrecv\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtpmap:111 opus/48000/2\r\n' +
    'a=rtcp-fb:111 transport-cc\r\n' +
    'a=fmtp:111 minptime=10;useinbandfec=1\r\n' +
    'a=rtpmap:103 ISAC/16000\r\n' +
    'a=rtpmap:104 ISAC/32000\r\n' +
    'a=rtpmap:9 G722/8000\r\n' +
    'a=rtpmap:102 ILBC/8000\r\n' +
    'a=rtpmap:0 PCMU/8000\r\n' +
    'a=rtpmap:8 PCMA/8000\r\n' +
    'a=rtpmap:106 CN/32000\r\n' +
    'a=rtpmap:105 CN/16000\r\n' +
    'a=rtpmap:13 CN/8000\r\n' +
    'a=rtpmap:110 telephone-event/48000\r\n' +
    'a=rtpmap:112 telephone-event/32000\r\n' +
    'a=rtpmap:113 telephone-event/16000\r\n' +
    'a=rtpmap:126 telephone-event/8000\r\n' +
    'a=ssrc:3496221613 cname:7efsTJMX4YNf740V\r\n' +
    'a=ssrc:3496221613 msid:4169861f-fa77-4c52-b0a7-da4673eb4512 8c0eb0bb-a1ab-422a-a527-5d5bc73635b7\r\n' +
    'a=ssrc:3496221613 mslabel:4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'a=ssrc:3496221613 label:8c0eb0bb-a1ab-422a-a527-5d5bc73635b7\r\n' +
    'm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:+CFh\r\n' +
    'a=ice-pwd:ccPSGw5U3fnoHysgp1bquCYJ\r\n' +
    'a=ice-options:trickle renomination\r\n' +
    'a=fingerprint:sha-256 2A:2B:C1:A4:1D:8C:B3:C3:B8:AA:6D:C2:36:71:F7:95:61:CC:54:E6:2D:79:C0:4D:A5:D4:E1:45:3D:00:BF:F4\r\n' +
    'a=setup:actpass\r\n' +
    'a=mid:video\r\n' +
    'a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n' +
    'a=extmap:13 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
    'a=extmap:3 urn:3gpp:video-orientation\r\n' +
    'a=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n' +
    'a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n' +
    'a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n' +
    'a=extmap:8 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07\r\n' +
    'a=extmap:9 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\n' +
    'a=sendrecv\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtcp-rsize\r\n' +
    'a=rtpmap:96 VP8/90000\r\n' +
    'a=rtcp-fb:96 goog-remb\r\n' +
    'a=rtcp-fb:96 transport-cc\r\n' +
    'a=rtcp-fb:96 ccm fir\r\n' +
    'a=rtcp-fb:96 nack\r\n' +
    'a=rtcp-fb:96 nack pli\r\n' +
    'a=rtpmap:97 rtx/90000\r\n' +
    'a=fmtp:97 apt=96\r\n' +
    'a=rtpmap:98 VP9/90000\r\n' +
    'a=rtcp-fb:98 goog-remb\r\n' +
    'a=rtcp-fb:98 transport-cc\r\n' +
    'a=rtcp-fb:98 ccm fir\r\n' +
    'a=rtcp-fb:98 nack\r\n' +
    'a=rtcp-fb:98 nack pli\r\n' +
    'a=rtpmap:99 rtx/90000\r\n' +
    'a=fmtp:99 apt=98\r\n' +
    'a=rtpmap:100 red/90000\r\n' +
    'a=rtpmap:101 rtx/90000\r\n' +
    'a=fmtp:101 apt=100\r\n' +
    'a=rtpmap:127 ulpfec/90000\r\n' +
    'a=ssrc-group:FID 1093641884 443757454\r\n' +
    'a=ssrc:1093641884 cname:7efsTJMX4YNf740V\r\n' +
    'a=ssrc:1093641884 msid:4169861f-fa77-4c52-b0a7-da4673eb4512 47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n' +
    'a=ssrc:1093641884 mslabel:4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'a=ssrc:1093641884 label:47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n' +
    'a=ssrc:443757454 cname:7efsTJMX4YNf740V\r\n' +
    'a=ssrc:443757454 msid:4169861f-fa77-4c52-b0a7-da4673eb4512 47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n' +
    'a=ssrc:443757454 mslabel:4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'a=ssrc:443757454 label:47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n',
  type: 'offer'
} 2
Sending candidate to: {
  candidate: 'candidate:3362660723 1 udp 2122260223 192.168.232.2 51977 typ host generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:1914131086 1 udp 2122187263 fec0::ff:fe44:5566 41727 typ host generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:3362660723 1 udp 2122260223 192.168.232.2 46626 typ host generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:1914131086 1 udp 2122187263 fec0::ff:fe44:5566 39496 typ host generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:842163049 1 udp 1686052607 189.133.49.117 60389 typ srflx raddr 192.168.232.2 rport 51977 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:4231669940 1 udp 1685989631 2806:106e:a:f03d:7d79:9dd4:5653:7381 60393 typ srflx raddr fec0::ff:fe44:5566 rport 41727 generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:4231669940 1 udp 1685989631 2806:106e:a:f03d:7d79:9dd4:5653:7381 60394 typ srflx raddr fec0::ff:fe44:5566 rport 39496 generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:842163049 1 udp 1686052607 189.133.49.117 60392 typ srflx raddr 192.168.232.2 rport 46626 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:2108125103 1 udp 41885439 172.31.19.115 64788 typ relay raddr 189.133.49.117 rport 60392 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:2108125103 1 udp 41885439 172.31.19.115 55279 typ relay raddr 189.133.49.117 rport 60389 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
</code>```

I don't know what am I doing wrong, but any help on what it is my problem would be appreciated.

答: There is a typo in onmessage on React Native. rename dcata to data. upvote if you find the answer useful.

Body:
I've been trying to learn WebRTC with React Native, so I've been working on this video call project. I thought I had it all figured out until this came up.

First of all, this is my React Native Code

import React, {useEffect, useState, useCallback} from 'react';
import {View, StyleSheet, Alert} from 'react-native';
import {Text} from 'react-native-paper';
import {Button} from 'react-native-paper';
import AsyncStorage from '@react-native-community/async-storage';
import {TextInput} from 'react-native-paper';

import {useFocusEffect} from '@react-navigation/native';

import InCallManager from 'react-native-incall-manager';

import {
  RTCPeerConnection,
  RTCIceCandidate,
  RTCSessionDescription,
  RTCView,
  MediaStream,
  MediaStreamTrack,
  mediaDevices,
  registerGlobals,
} from 'react-native-webrtc';

export default function CallScreen({navigation, ...props}) {
  let name;
  let connectedUser;
  const [userId, setUserId] = useState('');
  const [socketActive, setSocketActive] = useState(false);
  const [calling, setCalling] = useState(false);
  // Video Scrs
  const [localStream, setLocalStream] = useState({toURL: () => null});
  const [remoteStream, setRemoteStream] = useState({toURL: () => null});
  const [conn, setConn] = useState(new WebSocket('ws://:4443/'));
  const [yourConn, setYourConn] = useState(
    new RTCPeerConnection({
      iceServers: [
        {
          urls: 'stun:stun.l.google.com:19302',
        }, {
          urls: 'stun:stun1.l.google.com:19302',
        }, {
          urls: 'stun:stun2.l.google.com:19302',
        }, {
          username: "",
          credential: "",
          urls: 'turn::3478',
        }, {
          username: "",
          credential: "",
          urls: 'stun::3478',
        }
      ],
    }),
  );

  const [offer, setOffer] = useState(null);

  const [callToUsername, setCallToUsername] = useState(null);

  useFocusEffect(
    useCallback(() => {
      AsyncStorage.getItem('userId').then(id => {
        console.log(id);
        if (id) {
          setUserId(id);
        } else {
          setUserId('');
          navigation.push('Login');
        }
      });
    }, [userId]),
  );

  useEffect(() => {
    navigation.setOptions({
      title: 'Hola' + userId,
      headerRight: () => (
        <Button mode="text" onPress={onLogout} style={{paddingRight: 10}}>
          Salir
        </Button>
      ),
    });
  }, [userId]);

  useEffect(() => {
    if (socketActive && userId.length > 0) {
      try {
        InCallManager.start({media: 'audio'});
        InCallManager.setForceSpeakerphoneOn(true);
        InCallManager.setSpeakerphoneOn(true);
      } catch (err) {
        console.log('InApp Caller ---------------------->', err);
      }

      console.log(InCallManager);

      send({
        type: 'login',
        name: userId,
      });
    }
  }, [socketActive, userId]);

  const onLogin = () => {};

  useEffect(() => {

    conn.onopen = () => {
      console.log('Connected to the signaling server');
      setSocketActive(true);
    };
    conn.onmessage = msg => {
      let data;
      if (msg.data === 'Hello world') {
        data = {};
      } else {
        dcata = JSON.parse(msg.data);
        console.log('Data --------------------->', data);
        switch (data.type) {
          case 'login':
            console.log('Login');
            break;
          case 'offer':
            handleOffer(data.offer, data.name);
            console.log('Offer');
            break;
          case 'answer':
            handleAnswer(data.answer);
            console.log('Answer');
            break;
          case 'candidate':
            handleCandidate(data.candidate);
            console.log('Candidate');
            break;
          case 'leave':
            handleLeave();
            console.log('Leave');
            break;
          default:
            break;
        }
      }
    };
    conn.onerror = function(err) {
      console.log('Got error', err);
    };

    let isFront = false;
    mediaDevices.enumerateDevices().then(sourceInfos => {
      let videoSourceId;
      for (let i = 0; i < sourceInfos.length; i++) {
        const sourceInfo = sourceInfos[i];
        if (
          sourceInfo.kind == 'videoinput' &&
          sourceInfo.facing == (isFront ? 'front' : 'environment')
        ) {
          videoSourceId = sourceInfo.deviceId;
        }
      }
      mediaDevices
        .getUserMedia({
          audio: true,
          video: {
            mandatory: {
              minWidth: 500,
              minHeight: 300,
              minFrameRate: 30,
            },
            facingMode: isFront ? 'user' : 'environment',
            optional: videoSourceId ? [{sourceId: videoSourceId}] : [],
          },
        })
        .then(stream => {
          setLocalStream(stream);

          yourConn.addStream(stream);
        })
        .catch(error => {

        });
    });

    yourConn.onaddstream = event => {
      console.log('On Add Stream', event);
      setRemoteStream(event.stream);
    };

    yourConn.onicecandidate = event => {
      if (event.candidate) {
        send({
          type: 'candidate',
          candidate: event.candidate,
        });
      }
    };
  }, []);

  const send = message => {
    if (connectedUser) {
      message.name = connectedUser;
      console.log('Connected iser in end----------', message);
    }

    conn.send(JSON.stringify(message));
  };

  const onCall = () => {
    setCalling(true);

    connectedUser = callToUsername;
    console.log('Caling to', callToUsername);

    yourConn.createOffer().then(offer => {
      yourConn.setLocalDescription(offer).then(() => {
        console.log('Sending Ofer');
        console.log(offer);
        send({
          type: 'offer',
          offer: offer,
        });
      });
    });
  };

  const handleOffer = async (offer, name) => {
    console.log(name + ' is calling you.');

    console.log('Accepting Call===========>', offer);
    connectedUser = name;

    try {
      await yourConn.setRemoteDescription(new RTCSessionDescription(offer));

      const answer = await yourConn.createAnswer();

      await yourConn.setLocalDescription(answer);
      send({
        type: 'answer',
        answer: answer,
      });
    } catch (err) {
      console.log('Offerr Error', err);
    }
  };

  const handleAnswer = answer => {
    yourConn.setRemoteDescription(new RTCSessionDescription(answer));
  };

  const handleCandidate = candidate => {
    setCalling(false);
    console.log('Candidate ----------------->', candidate);
    yourConn.addIceCandidate(new RTCIceCandidate(candidate));
  };

  const hangUp = () => {
    send({
      type: 'leave',
    });

    handleLeave();
  };

  const handleLeave = () => {
    connectedUser = null;
    setRemoteStream({toURL: () => null});

    yourConn.close();

  };

  const onLogout = () => {

    AsyncStorage.removeItem('userId').then(res => {
      navigation.push('Login');
    });
  };

  const acceptCall = async () => {
    console.log('Accepting Call===========>', offer);
    connectedUser = offer.name;

    try {
      await yourConn.setRemoteDescription(new RTCSessionDescription(offer));

      const answer = await yourConn.createAnswer();

      await yourConn.setLocalDescription(answer);

      send({
        type: 'answer',
        answer: answer,
      });
    } catch (err) {
      console.log('Offerr Error', err);
    }
  };
  const rejectCall = async () => {
    send({
      type: 'leave',
    });
    ``;
    setOffer(null);

    handleLeave();
  };

  return (
    <View style={styles.root}>
      <View style={styles.inputField}>
        <TextInput
          label="Ingresa el ID del familiar"
          mode="outlined"
          style={{marginBottom: 7}}
          onChangeText={text => setCallToUsername(text)}
        />
        <Button
          mode="contained"
          onPress={onCall}
          loading={calling}
          //   style={styles.btn}
          contentStyle={styles.btnContent}
          disabled={!(socketActive && userId.length > 0)}>
          Llamar
        </Button>
      </View>

      <View style={styles.videoContainer}>
        <View style={[styles.videos, styles.localVideos]}>
          <Text>Tu video</Text>
          <RTCView streamURL={localStream.toURL()} style={styles.localVideo} />
        </View>
        <View style={[styles.videos, styles.remoteVideos]}>
          <Text>Video del familiar</Text>
          <RTCView
            streamURL={remoteStream.toURL()}
            style={styles.remoteVideo}
          />
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  root: {
    backgroundColor: '#fff',
    flex: 1,
    padding: 20,
  },
  inputField: {
    marginBottom: 10,
    flexDirection: 'column',
  },
  videoContainer: {
    flex: 1,
    minHeight: 450,
  },
  videos: {
    width: '100%',
    flex: 1,
    position: 'relative',
    overflow: 'hidden',

    borderRadius: 6,
  },
  localVideos: {
    height: 100,
    marginBottom: 10,
  },
  remoteVideos: {
    height: 400,
  },
  localVideo: {
    backgroundColor: '#f2f2f2',
    height: '100%',
    width: '100%',
  },
  remoteVideo: {
    backgroundColor: '#f2f2f2',
    height: '100%',
    width: '100%',
  },
});

At this point is worth to mention that my STUN/TURN server works perfectly, and this is my signaling socket

var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer({port: 4443});
var users = {};

wss.on('connection', function(connection) {

   console.log('User connected');

   //when server gets a message from a connected user
   connection.on('message', function(message) {

      var data;
      //accepting only JSON messages
      try {
         data = JSON.parse(message);
      } catch (e) {
         console.log('Invalid JSON');
         data = {};
      }

      //switching type of the user message
      switch (data.type) {
         //when a user tries to login

         case 'login':
            console.log('User logged', data.name);

            //if anyone is logged in with this username then refuse
            if(users[data.name]) {
               sendTo(connection, {
                  type: 'login',
                  success: false
               });
            } else {
               //save user connection on the server
               users[data.name] = connection;
               connection.name = data.name;

               sendTo(connection, {
                  type: 'login',
                  success: true
               });
            }

            break;

         case 'offer':
            //for ex. UserA wants to call UserB
            console.log('Sending offer to: ', data.offer, data.name);

            //if UserB exists then send him offer details
            var conn = users[data.name];

            if(conn != null) {
               //setting that UserA connected with UserB
               connection.otherName = data.name;

               sendTo(conn, {
                  type: 'offer',
                  offer: data.offer,
                  name: connection.name
               });
            }

            break;

         case 'answer':
            console.log('Sending answer to: ', data.answer);
            //for ex. UserB answers UserA
            var conn = users[data.answer];

            if(conn != null) {
               connection.otherName = data.name;
               sendTo(conn, {
                  type: 'answer',
                  answer: data.answer
               });
            }

            break;

         case 'candidate':
            console.log("Sending candidate to:",data.name);
            var conn = users[data.name];

            if(conn != null) {
               sendTo(conn, {
                  type: 'candidate',
                  candidate: data.candidate
               });
            }

            break;

         case 'leave':
            console.log('Disconnecting from', data.name);
            var conn = users[data.name];
            conn.otherName = null;

            //notify the other user so he can disconnect his peer connection
            if(conn != null) {
               sendTo(conn, {
                  type: 'leave'
               });
            }

            break;

         default:
            sendTo(connection, {
               type: 'error',
               message: 'Command not found: ' + data.type
            });

            break;
      }
   });

   //when user exits, for example closes a browser window
   //this may help if we are still in "offer","answer" or "candidate" state
   connection.on('close', function() {

      if(connection.name) {
      delete users[connection.name];

         if(connection.otherName) {
            console.log('Disconnecting from ', connection.otherName);
            var conn = users[connection.otherName];
            conn.otherName = null;

            if(conn != null) {
               sendTo(conn, {
                  type: 'leave'
               });
            }
         }
      }
   });

   connection.send('Hello world');

});

function sendTo(connection, message) {
   connection.send(JSON.stringify(message));
}

But here si where the problems begin.

When I use the App to login this is what the Socket shows.

User connected
User connected
User connected
User logged 1
User connected
User connected
User connected
User connected
User connected

But immediately, the app shows this.

And if I dismiss the error and try to Call another peer that is already conected, the error shows on the device I try to Call.

The React Native cli, tells me the same as the error

Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.
[Tue Jun 02 2020 10:34:26.400]  LOG      Running "webrtcApp" with {"rootTag":1}
[Tue Jun 02 2020 10:37:20.365]  LOG      Connected to the signaling server
[Tue Jun 02 2020 10:37:20.487]  LOG      1
[Tue Jun 02 2020 10:37:20.747]  LOG      {"audioUriMap": {"busytone": {"_BUNDLE_": null, "_DEFAULT_": null}, "ringback": {"_BUNDLE_": null, "_DEFAULT_": null}, "ringtone": {"_BUNDLE_": null, "_DEFAULT_": null}}, "cameraPermission": "granted", "checkCameraPermission": [Function bound checkCameraPermission], "checkRecordPermission": [Function bound checkRecordPermission], "recordPermission": "granted", "requestCameraPermission": [Function bound requestCameraPermission], "requestRecordPermission": [Function bound requestRecordPermission], "vibrate": false}
[Tue Jun 02 2020 10:37:20.914]  LOG      1
[Tue Jun 02 2020 10:37:20.933]  LOG      Data ---------------------> undefined
[Tue Jun 02 2020 10:37:52.746]  LOG      Data ---------------------> undefined

And here it is what the socket shows when I try to call another peer that is Connected.

Sending offer to:  {
  sdp: 'v=0\r\n' +
    'o=- 3903065942025360998 2 IN IP4 127.0.0.1\r\n' +
    's=-\r\n' +
    't=0 0\r\n' +
    'a=group:BUNDLE audio video\r\n' +
    'a=msid-semantic: WMS 4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 102 0 8 106 105 13 110 112 113 126\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:+CFh\r\n' +
    'a=ice-pwd:ccPSGw5U3fnoHysgp1bquCYJ\r\n' +
    'a=ice-options:trickle renomination\r\n' +
    'a=fingerprint:sha-256 2A:2B:C1:A4:1D:8C:B3:C3:B8:AA:6D:C2:36:71:F7:95:61:CC:54:E6:2D:79:C0:4D:A5:D4:E1:45:3D:00:BF:F4\r\n' +
    'a=setup:actpass\r\n' +
    'a=mid:audio\r\n' +
    'a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n' +
    'a=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=sendrecv\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtpmap:111 opus/48000/2\r\n' +
    'a=rtcp-fb:111 transport-cc\r\n' +
    'a=fmtp:111 minptime=10;useinbandfec=1\r\n' +
    'a=rtpmap:103 ISAC/16000\r\n' +
    'a=rtpmap:104 ISAC/32000\r\n' +
    'a=rtpmap:9 G722/8000\r\n' +
    'a=rtpmap:102 ILBC/8000\r\n' +
    'a=rtpmap:0 PCMU/8000\r\n' +
    'a=rtpmap:8 PCMA/8000\r\n' +
    'a=rtpmap:106 CN/32000\r\n' +
    'a=rtpmap:105 CN/16000\r\n' +
    'a=rtpmap:13 CN/8000\r\n' +
    'a=rtpmap:110 telephone-event/48000\r\n' +
    'a=rtpmap:112 telephone-event/32000\r\n' +
    'a=rtpmap:113 telephone-event/16000\r\n' +
    'a=rtpmap:126 telephone-event/8000\r\n' +
    'a=ssrc:3496221613 cname:7efsTJMX4YNf740V\r\n' +
    'a=ssrc:3496221613 msid:4169861f-fa77-4c52-b0a7-da4673eb4512 8c0eb0bb-a1ab-422a-a527-5d5bc73635b7\r\n' +
    'a=ssrc:3496221613 mslabel:4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'a=ssrc:3496221613 label:8c0eb0bb-a1ab-422a-a527-5d5bc73635b7\r\n' +
    'm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:+CFh\r\n' +
    'a=ice-pwd:ccPSGw5U3fnoHysgp1bquCYJ\r\n' +
    'a=ice-options:trickle renomination\r\n' +
    'a=fingerprint:sha-256 2A:2B:C1:A4:1D:8C:B3:C3:B8:AA:6D:C2:36:71:F7:95:61:CC:54:E6:2D:79:C0:4D:A5:D4:E1:45:3D:00:BF:F4\r\n' +
    'a=setup:actpass\r\n' +
    'a=mid:video\r\n' +
    'a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n' +
    'a=extmap:13 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
    'a=extmap:3 urn:3gpp:video-orientation\r\n' +
    'a=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n' +
    'a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n' +
    'a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n' +
    'a=extmap:8 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07\r\n' +
    'a=extmap:9 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\n' +
    'a=sendrecv\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtcp-rsize\r\n' +
    'a=rtpmap:96 VP8/90000\r\n' +
    'a=rtcp-fb:96 goog-remb\r\n' +
    'a=rtcp-fb:96 transport-cc\r\n' +
    'a=rtcp-fb:96 ccm fir\r\n' +
    'a=rtcp-fb:96 nack\r\n' +
    'a=rtcp-fb:96 nack pli\r\n' +
    'a=rtpmap:97 rtx/90000\r\n' +
    'a=fmtp:97 apt=96\r\n' +
    'a=rtpmap:98 VP9/90000\r\n' +
    'a=rtcp-fb:98 goog-remb\r\n' +
    'a=rtcp-fb:98 transport-cc\r\n' +
    'a=rtcp-fb:98 ccm fir\r\n' +
    'a=rtcp-fb:98 nack\r\n' +
    'a=rtcp-fb:98 nack pli\r\n' +
    'a=rtpmap:99 rtx/90000\r\n' +
    'a=fmtp:99 apt=98\r\n' +
    'a=rtpmap:100 red/90000\r\n' +
    'a=rtpmap:101 rtx/90000\r\n' +
    'a=fmtp:101 apt=100\r\n' +
    'a=rtpmap:127 ulpfec/90000\r\n' +
    'a=ssrc-group:FID 1093641884 443757454\r\n' +
    'a=ssrc:1093641884 cname:7efsTJMX4YNf740V\r\n' +
    'a=ssrc:1093641884 msid:4169861f-fa77-4c52-b0a7-da4673eb4512 47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n' +
    'a=ssrc:1093641884 mslabel:4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'a=ssrc:1093641884 label:47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n' +
    'a=ssrc:443757454 cname:7efsTJMX4YNf740V\r\n' +
    'a=ssrc:443757454 msid:4169861f-fa77-4c52-b0a7-da4673eb4512 47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n' +
    'a=ssrc:443757454 mslabel:4169861f-fa77-4c52-b0a7-da4673eb4512\r\n' +
    'a=ssrc:443757454 label:47eb8496-acdf-48ae-a7bb-bb44e758b23e\r\n',
  type: 'offer'
} 2
Sending candidate to: {
  candidate: 'candidate:3362660723 1 udp 2122260223 192.168.232.2 51977 typ host generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:1914131086 1 udp 2122187263 fec0::ff:fe44:5566 41727 typ host generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:3362660723 1 udp 2122260223 192.168.232.2 46626 typ host generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:1914131086 1 udp 2122187263 fec0::ff:fe44:5566 39496 typ host generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:842163049 1 udp 1686052607 189.133.49.117 60389 typ srflx raddr 192.168.232.2 rport 51977 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:4231669940 1 udp 1685989631 2806:106e:a:f03d:7d79:9dd4:5653:7381 60393 typ srflx raddr fec0::ff:fe44:5566 rport 41727 generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}
Sending candidate to: {
  candidate: 'candidate:4231669940 1 udp 1685989631 2806:106e:a:f03d:7d79:9dd4:5653:7381 60394 typ srflx raddr fec0::ff:fe44:5566 rport 39496 generation 0 ufrag +CFh network-id 4 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:842163049 1 udp 1686052607 189.133.49.117 60392 typ srflx raddr 192.168.232.2 rport 46626 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:2108125103 1 udp 41885439 172.31.19.115 64788 typ relay raddr 189.133.49.117 rport 60392 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 1,
  sdpMid: 'video'
}
Sending candidate to: {
  candidate: 'candidate:2108125103 1 udp 41885439 172.31.19.115 55279 typ relay raddr 189.133.49.117 rport 60389 generation 0 ufrag +CFh network-id 3 network-cost 10',
  sdpMLineIndex: 0,
  sdpMid: 'audio'
}

I don't know what am I doing wrong, but any help on what it is my problem would be appreciated.


来源: stackexchange

问:
process.env.NODE_ENV always 'development' when building nestjs app with nrwl nx
My NX application's npm run build:server calls ng build api-server that triggers the @nrwl/node:build builder.

It builds the NestJS application as main.js. Things work except I wanted process.env.NODE_ENV to be evaluated at runtime but I think it was resolved at build time (via Webpack).

Currently, the value is always set to 'development'.

I am new to Nrwl's NX. Any solution this?

答:
The reason you're seeing development is because you're building the app in development mode - it's not best practice to evaluate at runtime because then the builder can't do fancy things to make the build production ready. If you want production, you need to build the app in production mode by adding the --prod flag (just like how you need to build Angular in production mode).

If you need to serve the app in production mode (instead of build) the default config doesn't provide you with a prod mode for serve. You'll need to add the configuration to your angular.json.

So this code:

```<code>"serve": {
      "builder": "@nrwl/node:execute",
      "options": {
        "buildTarget": "api-server:build"
      }
    },
</code>```

Would become

```<code>"serve": {
      "builder": "@nrwl/node:execute",
      "options": {
        "buildTarget": "api-server:build"
      },
      "configurations": {
        "production": {
          "buildTarget": "api-server:build:production"
        }
      }
    },
</code>```

and then you can run

```<code>ng serve --project=api-server --prod
</code>```

ContentLicense: CC BY-SA 4.0

Body:
The reason you're seeing development is because you're building the app in development mode - it's not best practice to evaluate at runtime because then the builder can't do fancy things to make the build production ready. If you want production, you need to build the app in production mode by adding the --prod flag (just like how you need to build Angular in production mode).

If you need to serve the app in production mode (instead of build) the default config doesn't provide you with a prod mode for serve. You'll need to add the configuration to your angular.json.

So this code:

"serve": {
      "builder": "@nrwl/node:execute",
      "options": {
        "buildTarget": "api-server:build"
      }
    },

Would become

"serve": {
      "builder": "@nrwl/node:execute",
      "options": {
        "buildTarget": "api-server:build"
      },
      "configurations": {
        "production": {
          "buildTarget": "api-server:build:production"
        }
      }
    },

and then you can run

ng serve --project=api-server --prod


问:
Receipt has overlapping text in Print Document
I am creating a print receipt in my POS project and attach picture of the output

my problem here is the overlapping of description, qty, price, amount.
How to show the qty and price and amount in the next line from this code?

```<code>e.Graphics.DrawString("Description" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, 260));
e.Graphics.DrawString("Qty" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(120, 260));
//e.Graphics.DrawString("UM" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(190, 190));
e.Graphics.DrawString("Price", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(155, 260));
e.Graphics.DrawString("Amount" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(205, 260));
e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, 275));

int yPos = 300;

foreach (var i in TempVal)
{
  e.Graphics.DrawString(i.Particular + " (" + i.UM + ")", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos));
  e.Graphics.DrawString(i.Qty, new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(120, yPos));
  //e.Graphics.DrawString(i.UM, new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(190, yPos));
  e.Graphics.DrawString(i.Price +".00", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(155, yPos));
  e.Graphics.DrawString(i.Total + ".00", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(205, yPos));

  yPos = yPos + 20;
}

e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, yPos));
e.Graphics.DrawString("Total Amount:                   Php " + label3.Text.Trim(), new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos+20));
e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, yPos+35));
e.Graphics.DrawString("Cash Tendered:                 Php " + label4.Text.Trim(), new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos + 55));
e.Graphics.DrawString("Change:                            Php " + lblTotal.Text.Trim(), new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos + 75));
e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, yPos+95));
</code>```

答:
This will “show the qty and price and amount in the next line” as you asked:

```<code>using (var f = new Font("trebuchet ms", 10, FontStyle.Regular))
{
    int yPos = 300;
    foreach (var v in TempVal)
    {
      e.Graphics.DrawString(v.Particular + " (" + v.UM + ")", f, Brushes.Black, new Point(0, yPos));
      yPos += 20;

      e.Graphics.DrawString(v.Qty, f, Brushes.Black, new Point(120, yPos));
      e.Graphics.DrawString(v.Price +".00", f, Brushes.Black, new Point(155, yPos));
      e.Graphics.DrawString(v.Total + ".00", f, Brushes.Black, new Point(205, yPos));
      yPos += 20;
    }
}
</code>```

Be aware this only works if TempVal is guaranteed to have so few records that they will all fit on one page. If there can be enough records to require more pages, you will have to calculate how many rows will fit on a page and split your output onto multiple pages.

Body:
I am creating a print receipt in my POS project and attach picture of the output

my problem here is the overlapping of description, qty, price, amount.
How to show the qty and price and amount in the next line from this code?

e.Graphics.DrawString("Description" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, 260));
e.Graphics.DrawString("Qty" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(120, 260));
//e.Graphics.DrawString("UM" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(190, 190));
e.Graphics.DrawString("Price", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(155, 260));
e.Graphics.DrawString("Amount" , new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(205, 260));
e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, 275));

int yPos = 300;

foreach (var i in TempVal)
{
  e.Graphics.DrawString(i.Particular + " (" + i.UM + ")", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos));
  e.Graphics.DrawString(i.Qty, new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(120, yPos));
  //e.Graphics.DrawString(i.UM, new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(190, yPos));
  e.Graphics.DrawString(i.Price +".00", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(155, yPos));
  e.Graphics.DrawString(i.Total + ".00", new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(205, yPos));

  yPos = yPos + 20;
}

e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, yPos));
e.Graphics.DrawString("Total Amount:                   Php " + label3.Text.Trim(), new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos+20));
e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, yPos+35));
e.Graphics.DrawString("Cash Tendered:                 Php " + label4.Text.Trim(), new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos + 55));
e.Graphics.DrawString("Change:                            Php " + lblTotal.Text.Trim(), new Font("trebuchet ms", 10, FontStyle.Regular), Brushes.Black, new Point(0, yPos + 75));
e.Graphics.DrawString("-------------------------------------------", new Font("trebuchet ms", 12, FontStyle.Regular), Brushes.Black, new Point(0, yPos+95));

Body:
This will “show the qty and price and amount in the next line” as you asked:

using (var f = new Font("trebuchet ms", 10, FontStyle.Regular))
{
    int yPos = 300;
    foreach (var v in TempVal)
    {
      e.Graphics.DrawString(v.Particular + " (" + v.UM + ")", f, Brushes.Black, new Point(0, yPos));
      yPos += 20;

      e.Graphics.DrawString(v.Qty, f, Brushes.Black, new Point(120, yPos));
      e.Graphics.DrawString(v.Price +".00", f, Brushes.Black, new Point(155, yPos));
      e.Graphics.DrawString(v.Total + ".00", f, Brushes.Black, new Point(205, yPos));
      yPos += 20;
    }
}

Be aware this only works if TempVal is guaranteed to have so few records that they will all fit on one page. If there can be enough records to require more pages, you will have to calculate how many rows will fit on a page and split your output onto multiple pages.


问:
Save DropdownButtons and TextField selected Data into a List
I'm trying to create an AlertDialog that will receive a Future-List or a List of the data from the Dropdownbuttons and the TextField that are inside of these Alert. In my App when I call these function for the AlertDialog, there will be 3 DropdownButtons and 1 TextField so the User can select the info that he wants, and then when he presses "OK" from the AlerDialog, the data he selected will be inside of the list, so I can use it with Firestore.

This is my AlertDialog:

```<code>Future<List> createAlertDialog(BuildContext context){

  return showDialog(context: context, builder: (ctx){
    return AlertDialog(
      title: Text('Text'),
      content: Column(
        children: [
          DropdownButton(
            value: iconNameSelected,
            items: iconlistdrop,
            hint: Text('Select Icon'),
            onChanged: (value) {
              iconNameSelected = value;
              setState(() {});
            },
          ),
          DropdownButton(
            value: activelabelSelected,
            items: activelistdrop,
            hint: Text('Select Active label'),
            onChanged: (value1) {
              activelabelSelected = value1;
              setState(() {});
            },
          ),
          DropdownButton(
            value: inactivelabelSelected,
            items: inactivelistdrop,
            hint: Text('Select InActive label'),
            onChanged: (value2) {
              inactivelabelSelected = value2;
              setState(() {});
            },
          ),
          TextField(
          ),
        ],
      ),
      actions: <Widget>[
        MaterialButton(
          elevation: 5.0,
          child: Text("OK"),
          onPressed: (){
            final values = [];
            Navigator.of(ctx).pop(values);
          },
        )
      ],
    );
  });
}
</code>```

Here's how I attempted to call it inside my InkWell widget:

```<code>createAlertDialog(context).then((value){
   printf(value[0]);
   printf(value[1]);
   printf(value[2]);
   printf(value[3]);
}
</code>```

Here's some extra stuff from the Data I have inserted inside the DropdownButtons:

```<code>List<DropdownMenuItem<String>> iconlistdrop = [];
List<DropdownMenuItem<String>> activelistdrop = [];
List<DropdownMenuItem<String>> inactivelistdrop = [];

String iconNameSelected = null;
String activelabelSelected = null;
String inactivelabelSelected = null;

void loadIcon () {
  iconlistdrop = [];
  iconlistdrop.add(DropdownMenuItem(
    child: Text('LightBulb'),
    value: 'lightbulbOutline',
  ));
  iconlistdrop.add(DropdownMenuItem(
    child: Text('Lock'),
    value: 'lock',
  ));
  iconlistdrop.add(DropdownMenuItem(
    child: Text('Check'),
    value: 'check',
  ));
}

void activelbl () {
  activelistdrop = [];
  activelistdrop.add(DropdownMenuItem(
    child: Text('On'),
    value: 'On',
  ));
  activelistdrop.add(DropdownMenuItem(
    child: Text('Locked'),
    value: 'Locked',
  ));
}

void inactivelbl () {
  inactivelistdrop = [];
  inactivelistdrop.add(DropdownMenuItem(
    child: Text('Off'),
    value: 'Off',
  ));
  inactivelistdrop.add(DropdownMenuItem(
    child: Text('Locked'),
    value: 'Unlocked',
  ));
}

loadIcon();
activelbl();
inactivelbl();
</code>```

My Class:

```<code>class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
var temperature;
var humidity;

Future getWeather() async {
http.Response response = await
 http.get('http://api.openweathermap.org/data/2.5/weather?
q=Curitiba&units=metric&appid=8c1ce29a0b974e97562564d892cd5a97');
var results = jsonDecode(response.body);
setState(() {
  this.temperature = results['main']['temp'];
  this.humidity = results['main']['humidity'];
});
}

@override
void initState () {
this.getWeather();
super.initState();
}

@override
Widget build(BuildContext context) {

final AuthService _auth = AuthService();

final user = Provider.of<User>(context);

Future getSubCollection(){
  return Firestore.instance.collection('dadosusuarios').document(user.uid).collection('buttons').getDocuments();
}
</code>```

答:
I would use a map for the values and separate the dialog to another widget and give it a constructor in case you might want it to have initial values. </p>

```<code>import 'package:flutter/material.dart';

class MyAlertDialog extends StatefulWidget {
  final Map<String, dynamic> initialValues;
  const MyAlertDialog({
    Key key,
    this.initialValues,
  }) : super(key: key);
  @override
  _MyAlertDialogState createState() => _MyAlertDialogState();
}

class _MyAlertDialogState extends State<MyAlertDialog> {
  Map<String, dynamic> _values;
  TextEditingController _controller;
  @override
  initState() {
    super.initState();
    _values = widget.initialValues ??
        {'input1': 'One', 'input2': 'Two', 'input3': 'Free', 'input4': 'Four'};
    _controller = TextEditingController(text: _values['input4']);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Text'),
      content: Column(
        children: [
          DropdownButton(
            value: _values['input1'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select Icon'),
            onChanged: (value1) {
              setState(() {
                _values['input1'] = value1;
              });
            },
          ),
          DropdownButton(
            value: _values['input2'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select Active label'),
            onChanged: (value2) {
              setState(() {
                _values['input2'] = value2;
              });
            },
          ),
          DropdownButton(
            value: _values['input3'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select InActive label'),
            onChanged: (value3) {
              setState(() {
                _values['input3'] = value3;
              });
            },
          ),
          TextField(
            controller: _controller,
          ),
        ],
      ),
      actions: <Widget>[
        MaterialButton(
          elevation: 5.0,
          child: Text("OK"),
          onPressed: () {
            _values['input4'] = _controller.text.trim();
            Navigator.of(context).pop(_values);
          },
        )
      ],
    );
  }
}
</code>```

<p>Here i look if there is a value passed from the constructor. If not put some defaults. Update the map with each user input change and finally once the dialog popped return the map. Using map here is better in my opinion and would make pushing the values to Firestore easier. </p>

```<code> var result = await showDialog(
             context: context,
             builder: (ctx) {
         return MyAlertDialog(initialValues: /* Your default values if exist*/ );
                              });
 print(result);
</code>```

Body:
I'm trying to create an AlertDialog that will receive a Future-List or a List of the data from the Dropdownbuttons and the TextField that are inside of these Alert. In my App when I call these function for the AlertDialog, there will be 3 DropdownButtons and 1 TextField so the User can select the info that he wants, and then when he presses "OK" from the AlerDialog, the data he selected will be inside of the list, so I can use it with Firestore.

This is my AlertDialog:

Future<List> createAlertDialog(BuildContext context){

  return showDialog(context: context, builder: (ctx){
    return AlertDialog(
      title: Text('Text'),
      content: Column(
        children: [
          DropdownButton(
            value: iconNameSelected,
            items: iconlistdrop,
            hint: Text('Select Icon'),
            onChanged: (value) {
              iconNameSelected = value;
              setState(() {});
            },
          ),
          DropdownButton(
            value: activelabelSelected,
            items: activelistdrop,
            hint: Text('Select Active label'),
            onChanged: (value1) {
              activelabelSelected = value1;
              setState(() {});
            },
          ),
          DropdownButton(
            value: inactivelabelSelected,
            items: inactivelistdrop,
            hint: Text('Select InActive label'),
            onChanged: (value2) {
              inactivelabelSelected = value2;
              setState(() {});
            },
          ),
          TextField(
          ),
        ],
      ),
      actions: <Widget>[
        MaterialButton(
          elevation: 5.0,
          child: Text("OK"),
          onPressed: (){
            final values = [];
            Navigator.of(ctx).pop(values);
          },
        )
      ],
    );
  });
}

Here's how I attempted to call it inside my InkWell widget:

createAlertDialog(context).then((value){
   printf(value[0]);
   printf(value[1]);
   printf(value[2]);
   printf(value[3]);
}

Here's some extra stuff from the Data I have inserted inside the DropdownButtons:

List<DropdownMenuItem<String>> iconlistdrop = [];
List<DropdownMenuItem<String>> activelistdrop = [];
List<DropdownMenuItem<String>> inactivelistdrop = [];

String iconNameSelected = null;
String activelabelSelected = null;
String inactivelabelSelected = null;

void loadIcon () {
  iconlistdrop = [];
  iconlistdrop.add(DropdownMenuItem(
    child: Text('LightBulb'),
    value: 'lightbulbOutline',
  ));
  iconlistdrop.add(DropdownMenuItem(
    child: Text('Lock'),
    value: 'lock',
  ));
  iconlistdrop.add(DropdownMenuItem(
    child: Text('Check'),
    value: 'check',
  ));
}

void activelbl () {
  activelistdrop = [];
  activelistdrop.add(DropdownMenuItem(
    child: Text('On'),
    value: 'On',
  ));
  activelistdrop.add(DropdownMenuItem(
    child: Text('Locked'),
    value: 'Locked',
  ));
}

void inactivelbl () {
  inactivelistdrop = [];
  inactivelistdrop.add(DropdownMenuItem(
    child: Text('Off'),
    value: 'Off',
  ));
  inactivelistdrop.add(DropdownMenuItem(
    child: Text('Locked'),
    value: 'Unlocked',
  ));
}

loadIcon();
activelbl();
inactivelbl();

My Class:

class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
var temperature;
var humidity;

Future getWeather() async {
http.Response response = await
 http.get('http://api.openweathermap.org/data/2.5/weather?
q=Curitiba&units=metric&appid=8c1ce29a0b974e97562564d892cd5a97');
var results = jsonDecode(response.body);
setState(() {
  this.temperature = results['main']['temp'];
  this.humidity = results['main']['humidity'];
});
}

@override
void initState () {
this.getWeather();
super.initState();
}

@override
Widget build(BuildContext context) {

final AuthService _auth = AuthService();

final user = Provider.of<User>(context);

Future getSubCollection(){
  return Firestore.instance.collection('dadosusuarios').document(user.uid).collection('buttons').getDocuments();
}

Body:
I would use a map for the values and separate the dialog to another widget and give it a constructor in case you might want it to have initial values.

import 'package:flutter/material.dart';

class MyAlertDialog extends StatefulWidget {
  final Map<String, dynamic> initialValues;
  const MyAlertDialog({
    Key key,
    this.initialValues,
  }) : super(key: key);
  @override
  _MyAlertDialogState createState() => _MyAlertDialogState();
}

class _MyAlertDialogState extends State<MyAlertDialog> {
  Map<String, dynamic> _values;
  TextEditingController _controller;
  @override
  initState() {
    super.initState();
    _values = widget.initialValues ??
        {'input1': 'One', 'input2': 'Two', 'input3': 'Free', 'input4': 'Four'};
    _controller = TextEditingController(text: _values['input4']);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Text'),
      content: Column(
        children: [
          DropdownButton(
            value: _values['input1'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select Icon'),
            onChanged: (value1) {
              setState(() {
                _values['input1'] = value1;
              });
            },
          ),
          DropdownButton(
            value: _values['input2'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select Active label'),
            onChanged: (value2) {
              setState(() {
                _values['input2'] = value2;
              });
            },
          ),
          DropdownButton(
            value: _values['input3'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select InActive label'),
            onChanged: (value3) {
              setState(() {
                _values['input3'] = value3;
              });
            },
          ),
          TextField(
            controller: _controller,
          ),
        ],
      ),
      actions: <Widget>[
        MaterialButton(
          elevation: 5.0,
          child: Text("OK"),
          onPressed: () {
            _values['input4'] = _controller.text.trim();
            Navigator.of(context).pop(_values);
          },
        )
      ],
    );
  }
}

Here i look if there is a value passed from the constructor. If not put some defaults. Update the map with each user input change and finally once the dialog popped return the map. Using map here is better in my opinion and would make pushing the values to Firestore easier.

 var result = await showDialog(
             context: context,
             builder: (ctx) {
         return MyAlertDialog(initialValues: /* Your default values if exist*/ );
                              });
 print(result);


问:
Can someone, please, tell me what is wrong? PLSQL in ORACLE APEX
```<code>```
create or replace procedure cauta_magazinee(supraf NUMBER) is
begin
 c_idd MAGAZINE.ID%TYPE;
 c_numee MAGAZINE.NUME%TYPE;
 c_nr_angg MAGAZINE.NR_ANGAJATI%TYPE;
 idcentru MAGAZIN_CENTRU.ID_CENTRU%TYPE;
 numecentru CENTRU_COMERCIAL.NUME%TYPE;

--dbms_output.put_line('Magazinele cu o supratata mai mica decat '||supraf||' m^3 sunt:');
declare cursor magazine_c is
  select ID, NUME, NR_ANGAJATI form MAGAZINE where SUPRAFATA<supraf;

  begin
    open magazine_c;
    loop
     fetch  magazine_c into c_idd, c_numee, c_nr_angg;
     exit when  magazine_c%NOTFOUND;
     select ID_CENTRU into idcentru from MAGAZIN_CENTRU where c_idd=ID_MAGAZIN;
     select NUME into numecentru from CENTRU_COMERCIAL where idcentru=ID;
     dbms_output.put_line(c_idd||' ' ||c_numee||' '||c_nr_angg|| ' din centrul comercial'||numecentru);
    end loop;
    close magazine_c;
  end;

end cauta_magazinee;
/

```
</code>```

I really don't know what is wrong...
It is written in PLSQL-oracle apex
I get that error but the code is correctly written

答:
Your statement "but the code is correctly written" is incorrect. The variables declaration for c_idd through numecentru is incorrect as they appear in the execution section of the outer block. The following is your code with annotations indicated by '<<'.

```<code>create or replace procedure cauta_magazinee(supraf NUMBER) is
begin                                    << initiates Execution Section of procedure
 c_idd MAGAZINE.ID%TYPE;                 <<
 c_numee MAGAZINE.NUME%TYPE;             <<  Defined in the
 c_nr_angg MAGAZINE.NR_ANGAJATI%TYPE;    <<  execution section of procedure
 idcentru MAGAZIN_CENTRU.ID_CENTRU%TYPE; <<
 numecentru CENTRU_COMERCIAL.NUME%TYPE;  <<

--dbms_output.put_line('Magazinele cu o supratata mai mica decat '||supraf||' m^3 sunt:');
declare cursor magazine_c is             << declare opens inner block
  select ID, NUME, NR_ANGAJATI form MAGAZINE where SUPRAFATA<supraf;

  begin                                  << Executation section of inner block
    open magazine_c;
    loop
     fetch  magazine_c into c_idd, c_numee, c_nr_angg;
     exit when  magazine_c%NOTFOUND;
     select ID_CENTRU into idcentru from MAGAZIN_CENTRU where c_idd=ID_MAGAZIN;
     select NUME into numecentru from CENTRU_COMERCIAL where idcentru=ID;
     dbms_output.put_line(c_idd||' ' ||c_numee||' '||c_nr_angg|| ' din centrul comercial'||numecentru);
    end loop;
    close magazine_c;
  end;                                   << closes inner block

end cauta_magazinee;                     << closes outer block
</code>```

One thing I have discovered over the years is: when you receive a compile error your code is NOT correct. You may not see the error but it's there. Trust the compiler it's going to win the battle every time.

To correct just elminate the unnecessary inner block:

```<code>create or replace procedure cauta_magazinee(supraf NUMBER) is

 c_idd MAGAZINE.ID%TYPE;
 c_numee MAGAZINE.NUME%TYPE;
 c_nr_angg MAGAZINE.NR_ANGAJATI%TYPE;
 idcentru MAGAZIN_CENTRU.ID_CENTRU%TYPE;
 numecentru CENTRU_COMERCIAL.NUME%TYPE;

 cursor magazine_c is
  select ID, NUME, NR_ANGAJATI form MAGAZINE where SUPRAFATA<supraf;

 begin
    open magazine_c;
    loop
     fetch  magazine_c into c_idd, c_numee, c_nr_angg;
     exit when  magazine_c%NOTFOUND;
     select ID_CENTRU into idcentru from MAGAZIN_CENTRU where c_idd=ID_MAGAZIN;
     select NUME into numecentru from CENTRU_COMERCIAL where idcentru=ID;
     dbms_output.put_line(c_idd||' ' ||c_numee||' '||c_nr_angg|| ' din centrul comercial'||numecentru);
    end loop;
    close magazine_c;
 end cauta_magazinee;
</code>```

Not sure how the Apex editor works but can try

```<code>show errors
or
select * from user_errors;
</code>```

To see actual pl/sql error messages.

Body:
```
create or replace procedure cauta_magazinee(supraf NUMBER) is
begin
 c_idd MAGAZINE.ID%TYPE;
 c_numee MAGAZINE.NUME%TYPE;
 c_nr_angg MAGAZINE.NR_ANGAJATI%TYPE;
 idcentru MAGAZIN_CENTRU.ID_CENTRU%TYPE;
 numecentru CENTRU_COMERCIAL.NUME%TYPE;

--dbms_output.put_line('Magazinele cu o supratata mai mica decat '||supraf||' m^3 sunt:');
declare cursor magazine_c is
  select ID, NUME, NR_ANGAJATI form MAGAZINE where SUPRAFATA<supraf;

  begin
    open magazine_c;
    loop
     fetch  magazine_c into c_idd, c_numee, c_nr_angg;
     exit when  magazine_c%NOTFOUND;
     select ID_CENTRU into idcentru from MAGAZIN_CENTRU where c_idd=ID_MAGAZIN;
     select NUME into numecentru from CENTRU_COMERCIAL where idcentru=ID;
     dbms_output.put_line(c_idd||' ' ||c_numee||' '||c_nr_angg|| ' din centrul comercial'||numecentru);
    end loop;
    close magazine_c;
  end;

end cauta_magazinee;
/

```

I really don't know what is wrong...
It is written in PLSQL-oracle apex
I get that error but the code is correctly written

Body:
Your statement "but the code is correctly written" is incorrect. The variables declaration for c_idd through numecentru is incorrect as they appear in the execution section of the outer block. The following is your code with annotations indicated by '<<'.

create or replace procedure cauta_magazinee(supraf NUMBER) is
begin                                    << initiates Execution Section of procedure
 c_idd MAGAZINE.ID%TYPE;                 <<
 c_numee MAGAZINE.NUME%TYPE;             <<  Defined in the
 c_nr_angg MAGAZINE.NR_ANGAJATI%TYPE;    <<  execution section of procedure
 idcentru MAGAZIN_CENTRU.ID_CENTRU%TYPE; <<
 numecentru CENTRU_COMERCIAL.NUME%TYPE;  <<

--dbms_output.put_line('Magazinele cu o supratata mai mica decat '||supraf||' m^3 sunt:');
declare cursor magazine_c is             << declare opens inner block
  select ID, NUME, NR_ANGAJATI form MAGAZINE where SUPRAFATA<supraf;

  begin                                  << Executation section of inner block
    open magazine_c;
    loop
     fetch  magazine_c into c_idd, c_numee, c_nr_angg;
     exit when  magazine_c%NOTFOUND;
     select ID_CENTRU into idcentru from MAGAZIN_CENTRU where c_idd=ID_MAGAZIN;
     select NUME into numecentru from CENTRU_COMERCIAL where idcentru=ID;
     dbms_output.put_line(c_idd||' ' ||c_numee||' '||c_nr_angg|| ' din centrul comercial'||numecentru);
    end loop;
    close magazine_c;
  end;                                   << closes inner block

end cauta_magazinee;                     << closes outer block

One thing I have discovered over the years is: when you receive a compile error your code is NOT correct. You may not see the error but it's there. Trust the compiler it's going to win the battle every time.

To correct just elminate the unnecessary inner block:

create or replace procedure cauta_magazinee(supraf NUMBER) is

 c_idd MAGAZINE.ID%TYPE;
 c_numee MAGAZINE.NUME%TYPE;
 c_nr_angg MAGAZINE.NR_ANGAJATI%TYPE;
 idcentru MAGAZIN_CENTRU.ID_CENTRU%TYPE;
 numecentru CENTRU_COMERCIAL.NUME%TYPE;

 cursor magazine_c is
  select ID, NUME, NR_ANGAJATI form MAGAZINE where SUPRAFATA<supraf;

 begin
    open magazine_c;
    loop
     fetch  magazine_c into c_idd, c_numee, c_nr_angg;
     exit when  magazine_c%NOTFOUND;
     select ID_CENTRU into idcentru from MAGAZIN_CENTRU where c_idd=ID_MAGAZIN;
     select NUME into numecentru from CENTRU_COMERCIAL where idcentru=ID;
     dbms_output.put_line(c_idd||' ' ||c_numee||' '||c_nr_angg|| ' din centrul comercial'||numecentru);
    end loop;
    close magazine_c;
 end cauta_magazinee;

Not sure how the Apex editor works but can try

show errors
or
select * from user_errors;

To see actual pl/sql error messages.


问:
Entity Framework Core and FOR JSON AUTO
Does EF Core support FOR JSON AUTO for SQL Server? I have views in my database and I would like to query the view (while filtering it with a WHERE clause) and return the data back to me as FOR JSON AUTO.

I would like to do something along these lines:

```<code>string json = context.UsersView.Where(x => x.Id == userId).ForJson();
UsersViewModel model = JsonConvert.DeserializeObject<UsersViewModel>(json);
</code>```

Or however the syntax would go. Point is, I would like to utilize SQL Server's FOR JSON AUTO clause. Does this exist? I would include the FOR JSON AUTO in my view definition, but that doesn't help me, as I cannot add a WHERE clause to the view if it's defined that way. Also, If I'm completely missing a better way to do this, please feel free. But remember, I want the POCO model to have nested objects.

I cannot find a clean way of doing this, though it would be extremely helpful because my views are pretty complex and it would be nice to just pass the FOR JSON result into an POCO model with it's nested objects, etc.

答:
Example SQL Procedure:

```<code>create procedure MyProcedure
(
    @Parameter int
)
as
begin
    declare @result nvarchar(max);
    set @result = (
        select u.*
              ,(
                select ue.*
                from UserEmails ue
                where ue.UserId = u.Id
                for json path, include_null_values
              ) as Emails
        from Users u
        where u.UserType = @Parameter
        for json path, include_null_values
    )
    select @result;
end
</code>```

Add the following extension class to a folder near your Context:
https://github.com/snickler/EFCore-FluentStoredProcedure/blob/master/EFCoreFluent/src/EFCoreFluent/EFExtensions.cs

This extension class will allow you to execute a procedure on your context, like this:

```<code>public async Task<MyProcedureModel> GetMyProcedureJsonModel(int userTypeId)
{
    string result = string.Empty;
    await _clientContext.LoadStoredProc("MyProcedure")
                    .WithSqlParam("@Parameter", userTypeId)
                    .ExecuteStoredProcAsync((handler) =>
                    {
                        result = handler.ReadToString();
                    });
    MyProcedureModel model = null;
    if (result != null)
    {
        model = JsonConvert.DeserializeObject<MyProcedureModel>(result);
    }
    return model;
}
</code>```

Title: Entity Framework Core and FOR JSON AUTO

Body:
Does EF Core support FOR JSON AUTO for SQL Server? I have views in my database and I would like to query the view (while filtering it with a WHERE clause) and return the data back to me as FOR JSON AUTO.

I would like to do something along these lines:

string json = context.UsersView.Where(x => x.Id == userId).ForJson();
UsersViewModel model = JsonConvert.DeserializeObject<UsersViewModel>(json);

Or however the syntax would go. Point is, I would like to utilize SQL Server's FOR JSON AUTO clause. Does this exist? I would include the FOR JSON AUTO in my view definition, but that doesn't help me, as I cannot add a WHERE clause to the view if it's defined that way. Also, If I'm completely missing a better way to do this, please feel free. But remember, I want the POCO model to have nested objects.

I cannot find a clean way of doing this, though it would be extremely helpful because my views are pretty complex and it would be nice to just pass the FOR JSON result into an POCO model with it's nested objects, etc.

Body:
Example SQL Procedure:

create procedure MyProcedure
(
    @Parameter int
)
as
begin
    declare @result nvarchar(max);
    set @result = (
        select u.*
              ,(
                select ue.*
                from UserEmails ue
                where ue.UserId = u.Id
                for json path, include_null_values
              ) as Emails
        from Users u
        where u.UserType = @Parameter
        for json path, include_null_values
    )
    select @result;
end

Add the following extension class to a folder near your Context:
https://github.com/snickler/EFCore-FluentStoredProcedure/blob/master/EFCoreFluent/src/EFCoreFluent/EFExtensions.cs

This extension class will allow you to execute a procedure on your context, like this:

public async Task<MyProcedureModel> GetMyProcedureJsonModel(int userTypeId)
{
    string result = string.Empty;
    await _clientContext.LoadStoredProc("MyProcedure")
                    .WithSqlParam("@Parameter", userTypeId)
                    .ExecuteStoredProcAsync((handler) =>
                    {
                        result = handler.ReadToString();
                    });
    MyProcedureModel model = null;
    if (result != null)
    {
        model = JsonConvert.DeserializeObject<MyProcedureModel>(result);
    }
    return model;
}


问:
vs code - Expected java package name error
I have a java project with the following directory structure (as required by Gradle's 'java' plugin, assuming all defaults).

```<code>projectRootDir
 - src/main/java/com/myproj/Sample.java
 - build.gradle
</code>```

And

```<code>// Sample.java code
package com.myproj;

public class Sample{
    ...
}
</code>```

Opening projectRootDir folder in VS Code shows the following package naming error in Sample.java:

The declared package "com.myproj" doesn't match the expected package "main.java.com.myproj"

How to make VS Code recognise/use the package mentioned in the code?

Note: I am using the following extensions: Language Support for Java(TM) by RedHat and Debugger for Java by Microsoft.

答: In my case, the problem was faustinoaq.javac-linter extension. I uninstall the linter extension and everything works.

ContentLicense: CC BY-SA 3.0

Body:
I have a java project with the following directory structure (as required by Gradle's 'java' plugin, assuming all defaults).

projectRootDir
 - src/main/java/com/myproj/Sample.java
 - build.gradle

And

// Sample.java code
package com.myproj;

public class Sample{
    ...
}

Opening projectRootDir folder in VS Code shows the following package naming error in Sample.java:

The declared package "com.myproj" doesn't match the expected package "main.java.com.myproj"

How to make VS Code recognise/use the package mentioned in the code?

Note: I am using the following extensions: Language Support for Java(TM) by RedHat and Debugger for Java by Microsoft.


问:
AWS Amplify: Confirm Signup with Email Verification
I'm trying to figure out how to proceed after receiving confirmation email from AWS after signing up using the code below:

import { Auth } from 'Amplify'

const auth() => {
  return Auth.signUp({
    username: email,
    password,
    attributes: {
      birthdate,
      email,
      given_name: firstName,
      family_name: lastName,
    },
  })
}
```

I tried to search for this but didn't find anything helpful so far. Did anyone have experience using Amplify and confirming email address (which is also username in my Cognito configuration)?

The code above works, I get the email, but when click on it I get redirected to /my-callback-url?username=643663f9-e36b-4333-9222-1118338abf04. Something like this - what is this username parameter here, how do I decode it?

Best,

Marko

答:
It depends on cognito settings. I set up cognito to return code (not the link like in your case). You need to confirm sign up with  return Auth.confirmSignUp(username, code);

docs are here https://docs.amplify.aws/lib/auth/emailpassword/q/platform/js

I tought that user is confirmed by simply visiting that link in your case. 643663f9-e36b-4333-9222-1118338abf0 is one time verification code.

Body:
I'm trying to figure out how to proceed after receiving confirmation email from AWS after signing up using the code below:

import { Auth } from 'Amplify'

const auth() => {
  return Auth.signUp({
    username: email,
    password,
    attributes: {
      birthdate,
      email,
      given_name: firstName,
      family_name: lastName,
    },
  })
}

I tried to search for this but didn't find anything helpful so far. Did anyone have experience using Amplify and confirming email address (which is also username in my Cognito configuration)?

The code above works, I get the email, but when click on it I get redirected to /my-callback-url?username=643663f9-e36b-4333-9222-1118338abf04. Something like this - what is this username parameter here, how do I decode it?

Best,

Marko


问:
How to share same Visual Studio project between different solutions? Different app.config and setttings.settings
The title doesn't entirely describe the actual question, since I was trying to fit a succinct enough description into a one-liner.

I have a C# project I want to share between two different solutions (.sln). The project is an application with a Main method. It requires use of settings.settings and app.config. Each of the two solutions requires  a reference to the same C# project, but for each solution, the app.config and settings.settings need to be specific to their solutions. So if project C is shared between solutions A and B, A includes C where C has an app.config specific to A, and B includes the same exact C project, but C has app.config specific to C.  Is there a way to do this? I'm trying to avoid having to copy the same project (i.e. C) to two different locations, because if I update that project in one solution, then I have to make the same changes in another solution.

Thanks

答:
The project I want to share is actually shared between two different source control locations. I want to share the same project (i.e. C) between a SVN server solution and a TFS server solution. One solution I came up with which works (for more than one shared project, too) is to link the app.config in from a directory/branch located above the share project's directory. So instead of using the app.config located within project C's directory, you can have 2 different workspaces, and above project C's directory there is a folder called ApplicationSettings which has the app.config file. Each workspace, for each different solution, can maintain its own ApplicatonSettings folder, but can maintain the exact same copy of the shared project from source control.

I have a project at codeplex:
http://wcfsilverlighthelper.codeplex.com/

That is a working example of what I mean. Look at the ApplicationSettings folder, and notice how the app.config files are used in the solution's T4 projects.


问:
javascript : compare content of two array of objects by some id and return true or false
i need a little help to compare two array of objects and look if the array A has the same content of array B by using an id who is inside both arrays, for example:

example false:

ArrayObjectA = [{
      id: 1,
      name: josh,
      age: 31
      },{
      id: 2,
      name: Kyle,
      age: 21}];

ArrayObjectB = [{
      id: 1,
      name: josh,
      age: 31
      }];

ArrayObjectB content is equals to ArrayObjectA => false

example true:

ArrayObjectA = [{
      id: 1,
      name: josh,
      age: 31
      },{
      id: 2,
      name: Kyle,
      age: 21}];

ArrayObjectB = [{
      id: 1,
      name: josh,
      age: 31
      },{
      id: 2,
      name: Kyle,
      age: 21}];

ArrayObjectB content is equals to ArrayObjectA => true

      ```

i found a library called lodash but i dont know if is useful.

any help is appreciated.

答:
We can get ids list from each array and check if all elements are equal

const compareArrays = (arr1, arr2) => {
  const ids1 = arr1.map(v => v.id).sort()
  const ids2 = arr2.map(v => v.id).sort()

  return ids1.length === ids2.length && ids1.every((v, ind) => v === ids2[ind])
}
```

Body:
i need a little help to compare two array of objects and look if the array A has the same content of array B by using an id who is inside both arrays, for example:

example false:

ArrayObjectA = [{
      id: 1,
      name: josh,
      age: 31
      },{
      id: 2,
      name: Kyle,
      age: 21}];

ArrayObjectB = [{
      id: 1,
      name: josh,
      age: 31
      }];

ArrayObjectB content is equals to ArrayObjectA => false

example true:

ArrayObjectA = [{
      id: 1,
      name: josh,
      age: 31
      },{
      id: 2,
      name: Kyle,
      age: 21}];

ArrayObjectB = [{
      id: 1,
      name: josh,
      age: 31
      },{
      id: 2,
      name: Kyle,
      age: 21}];

ArrayObjectB content is equals to ArrayObjectA => true

i found a library called lodash but i dont know if is useful.

any help is appreciated.


问:
padding and colour not applying to body class
I have been trying to apply padding and colour to my body element and it is not applying.

I have been on this and it is not working. I am using live server for my work though, I will apply my code below for review. both the css and the html. it should also be noted that I am using SASS. Thanks

body {
    font-family: 'lato', sans-serif;
   font-weight: 400;
   //font-size: 16px;
   line-height: 1.7;
   color: $color-grey-dark;
    padding: 3rem;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <link href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700,900" rel="stylesheet">

            <link rel="stylesheet" href="css/icon-font.css">
            <link rel="stylesheet" href="css/style.css">
            <title>A7A ASSOCIATES LTD</title>
        </head>
        <body>
            <header class="header">
                <div class="header__logo-box">
                 <img src="img/A7A  Logo.png" alt="logo" class="header__logo">
                </div>
                <nav></nav>
            </header>
        </body>
    </html></code>```

答:
Why would you place those CSS rules after the HTML closing tag ?

anyway, here are few solutions:

put the CSS style inside css/style.css file and it shall work.

make sure the path to the CSS file is correct.

clear the browser cache and try again (CTRL+F5 for Firefox, Shift+F5 for chrome)

Body:
I have been trying to apply padding and colour to my body element and it is not applying.

I have been on this and it is not working. I am using live server for my work though, I will apply my code below for review. both the css and the html. it should also be noted that I am using SASS. Thanks

body {
    font-family: 'lato', sans-serif;
   font-weight: 400;
   //font-size: 16px;
   line-height: 1.7;
   color: $color-grey-dark;
    padding: 3rem;
}

            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <link href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700,900" rel="stylesheet">

            <link rel="stylesheet" href="css/icon-font.css">
            <link rel="stylesheet" href="css/style.css">
            <title>A7A ASSOCIATES LTD</title>


问:
How to parse Firebase Dynamic Link parameter values and put it in a variable?
I'm building an app that can receive Firebase's Dynamic Links and redirects it into a certain UIViewController. I've followed the steps on this video, but there's something that I still don't understand. So after I followed the steps above, I print my link on the debug area to something like this:

Incoming link parameter is https://play.google.com/store/apps/details?id=com.xxx.xxx&referrer=utm_source%3DXXX%26utm_medium%3Dxxx%26utm_campaign%3DXXX

Parameter id has a value of com.xxx.xxx

Parameter referrer has a value of utm_source=XXX&utm_medium=xxx&utm_campaign=XXX

This works perfectly, but what I want to do is I want to get the values of utm_source, utm_medium and utm_campaign and store it into a variable. I'm still uncertain on how do I manage to achieve this. Here is my code:

```<code>func handleIncomingDynamicLink(_ dynamicLink: DynamicLink) {
        guard let url = dynamicLink.url else {
            print("Dynamic Link has no URL")
            return
        }

        print("Incoming link parameter is \(url.absoluteString)")
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let queryItems = components.queryItems else { return }
        for queryItem in queryItems {
            print("Parameter \(queryItem.name) has a value of \(queryItem.value ?? "")")
        }
    }
</code>```

So how do I manage to do this? Feel free to ask if you need any more information. Thank you.

答:
Here's is how you can make a struct and assign the values to it.

struct MyVariable {
    var referrer: String?, utm_source: String?, utm_medium: String?, utm_campaign: String?
}

func handleIncomingDynamicLink(_ dynamicLink: URL?) {
    guard let string = dynamicLink?.absoluteString.removingPercentEncoding,
        let url = URL(string: string) else {
            print("Dynamic Link has no URL")
            return
    }
    var myVariable = MyVariable()
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
        let queryItems = components.queryItems else { return }
    for queryItem in queryItems {
        if queryItem.name == "referrer" {
            myVariable.referrer = queryItem.value
        } else if queryItem.name == "utm_source" {
            myVariable.utm_source = queryItem.value
        } else if queryItem.name == "utm_medium" {
            myVariable.utm_medium = queryItem.value
        } else if queryItem.name == "utm_campaign" {
            myVariable.utm_campaign = queryItem.value
        }
    }
    print("MyVariable: \(myVariable)")
}
```

Body:
I'm building an app that can receive Firebase's Dynamic Links and redirects it into a certain UIViewController. I've followed the steps on this video, but there's something that I still don't understand. So after I followed the steps above, I print my link on the debug area to something like this:

Incoming link parameter is https://play.google.com/store/apps/details?id=com.xxx.xxx&referrer=utm_source%3DXXX%26utm_medium%3Dxxx%26utm_campaign%3DXXX

Parameter id has a value of com.xxx.xxx

Parameter referrer has a value of utm_source=XXX&utm_medium=xxx&utm_campaign=XXX

This works perfectly, but what I want to do is I want to get the values of utm_source, utm_medium and utm_campaign and store it into a variable. I'm still uncertain on how do I manage to achieve this. Here is my code:

func handleIncomingDynamicLink(_ dynamicLink: DynamicLink) {
        guard let url = dynamicLink.url else {
            print("Dynamic Link has no URL")
            return
        }

        print("Incoming link parameter is \(url.absoluteString)")
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let queryItems = components.queryItems else { return }
        for queryItem in queryItems {
            print("Parameter \(queryItem.name) has a value of \(queryItem.value ?? "")")
        }
    }

So how do I manage to do this? Feel free to ask if you need any more information. Thank you.


问:
Display data from database with Select Option Codeigniter
first I want to apologize because I just learned Codeigniter, I have problems to display data from the database by using the Select Option, there is no error but the data does not appear, for your information, i have joined 3 tables.

Here's my Controller

```<code>class Harga extends CI_Controller{

function __construct(){
parent::__construct();
  $this->load->model('m_harga');
  $this->load->helper('url');
  $this->load->database();
}

function index(){
  $this->load->helper('form');
  $data['tabel_harga'] = $this->m_harga->tampil_data();
  $this->load->view('v_harga',$data);
}
</code>```

Here's my Model

```<code>class M_harga extends CI_Model{
 function tampil_data(){
    $this->db->order_by('id_harga','ASC');
    return $this->db->from('tabel_harga')
    ->join('tabel_vendor','tabel_vendor.id_vendor=tabel_harga.id_vendor')
    ->join('tabel_hari','tabel_hari.id_hari=tabel_harga.id_hari')
    ->get()
    ->result();
}
</code>```

and Here's my Views

```<code><select class="form-control">
    <option value="">All</option>
      <?php
       foreach($tabel_harga as $u)
       {
        echo '<option value="'.$u['id_vendor'].'">'.$u['nama_vendor'].'</option>';
       }
      ?>
</select>
</code>```

I will be very grateful if you help me, thank you guys.

答:
The data doesn't appear probably because you're using result() which returns object and you're getting data as array in your view.

Model

```<code>class M_harga extends CI_Model{

    function tampil_data(){

        $this->db->select('*');
        $this->db->from('tabel_harga');
        $this->db->join('tabel_vendor','tabel_vendor.id_vendor=tabel_harga.id_vendor', 'INNER');
        $this->db->join('tabel_hari','tabel_hari.id_hari=tabel_harga.id_hari', 'INNER');
        $this->db->order_by('id_harga','ASC');

        $query = $this->db->get()->result_array(); // use result_array() instead of result() as you're getting value as an array in your view.

        return $query;
    }
}
</code>```

Also, make sure to check $tabel_harga for values in your view ie

```<code><select class="form-control">
    <option value="">All</option>
      <?php
          if(!empty($tabel_harga)){
              foreach($tabel_harga as $u){
      ?>
                  <option value="<?php echo $u['id_vendor']; ?>"><?php echo $u['nama_vendor']; ?></option>
      <?php
              }
          }
      ?>
</select>
</code>```

Hope this helps you.

Body:
first I want to apologize because I just learned Codeigniter, I have problems to display data from the database by using the Select Option, there is no error but the data does not appear, for your information, i have joined 3 tables.

Here's my Controller

class Harga extends CI_Controller{

function __construct(){
parent::__construct();
  $this->load->model('m_harga');
  $this->load->helper('url');
  $this->load->database();
}

function index(){
  $this->load->helper('form');
  $data['tabel_harga'] = $this->m_harga->tampil_data();
  $this->load->view('v_harga',$data);
}

Here's my Model

class M_harga extends CI_Model{
 function tampil_data(){
    $this->db->order_by('id_harga','ASC');
    return $this->db->from('tabel_harga')
    ->join('tabel_vendor','tabel_vendor.id_vendor=tabel_harga.id_vendor')
    ->join('tabel_hari','tabel_hari.id_hari=tabel_harga.id_hari')
    ->get()
    ->result();
}

and Here's my Views

<select class="form-control">
    <option value="">All</option>
      <?php
       foreach($tabel_harga as $u)
       {
        echo '<option value="'.$u['id_vendor'].'">'.$u['nama_vendor'].'</option>';
       }
      ?>
</select>

I will be very grateful if you help me, thank you guys.

Body:
The data doesn't appear probably because you're using result() which returns object and you're getting data as array in your view.

Model

class M_harga extends CI_Model{

    function tampil_data(){

        $this->db->select('*');
        $this->db->from('tabel_harga');
        $this->db->join('tabel_vendor','tabel_vendor.id_vendor=tabel_harga.id_vendor', 'INNER');
        $this->db->join('tabel_hari','tabel_hari.id_hari=tabel_harga.id_hari', 'INNER');
        $this->db->order_by('id_harga','ASC');

        $query = $this->db->get()->result_array(); // use result_array() instead of result() as you're getting value as an array in your view.

        return $query;
    }
}

Also, make sure to check $tabel_harga for values in your view ie

<select class="form-control">
    <option value="">All</option>
      <?php
          if(!empty($tabel_harga)){
              foreach($tabel_harga as $u){
      ?>
                  <option value="<?php echo $u['id_vendor']; ?>"><?php echo $u['nama_vendor']; ?></option>
      <?php
              }
          }
      ?>
</select>

Hope this helps you.